# Implementation Plan: GUID Context Resolver & Human-Readable Reference Presentation **Branch**: `132-guid-context-resolver` | **Date**: 2026-03-10 | **Spec**: [spec.md](./spec.md) **Input**: Feature specification from `/specs/132-guid-context-resolver/spec.md` ## Summary Replace GUID-first reference display on core enterprise surfaces by extending the existing shared related-context/navigation work into a broader reference-resolution foundation. The implementation will introduce explicit reference descriptor and resolved-reference contracts, a resolver registry for internal and provider-backed references, and shared compact/detail rendering patterns so findings, baseline snapshots, operation runs, assignments, and related-context sections show names first, type and state second, and technical IDs only as secondary evidence. ## Technical Context **Language/Version**: PHP 8.4.15 / Laravel 12 **Primary Dependencies**: Filament v5, Livewire v4.0+, Tailwind CSS v4 **Storage**: PostgreSQL via Laravel Sail plus existing workspace and tenant context, existing Eloquent relations, and provider-derived identifiers already stored in domain records **Testing**: Pest v4 feature and unit tests on PHPUnit 12 **Target Platform**: Laravel Sail web application with workspace-admin routes under `/admin`, tenant-context routes under `/admin/t/{tenant}/...`, and shared Filament infolist/table rendering patterns **Project Type**: Laravel monolith / Filament web application **Performance Goals**: Reference rendering remains DB-only at page render time, uses bounded eager loading and batched local lookups, introduces no render-time Graph/provider calls, and avoids new N+1 patterns on dense list surfaces **Constraints**: No schema changes, no new Graph calls, no unauthorized existence leakage, no page-specific fallback logic for supported classes, no broken pages when a resolver is missing, preserve 404 vs 403 semantics, and keep technical IDs visibly secondary **Scale/Scope**: One shared resolver registry and value-object model, 8 to 10 initial reference classes, compact plus detailed presentation variants, 5 primary target surface families, and focused regression coverage for state rendering, linking, and authorization-aware degradation ## Constitution Check *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* - Inventory-first: PASS — the feature changes reference presentation only; inventory, snapshot, and backup persistence semantics remain unchanged. - Read/write separation: PASS — no write flow or new mutation is introduced; the feature is read-only UI and support-layer work. - Graph contract path: PASS — no new Microsoft Graph calls are introduced, and reference resolution must stay DB-only or source-context-only at render time. - Deterministic capabilities: PASS — linkability and degraded-state behavior can be derived from existing gates, policies, capability registries, and current route helpers. - RBAC-UX planes and isolation: PASS — the feature spans workspace-admin `/admin` and tenant-context `/admin/t/{tenant}/...` surfaces but must preserve 404 for non-members and 403 for in-scope capability denial. - Workspace isolation: PASS — workspace membership remains the visibility boundary for workspace-level reference labels and canonical destinations. - RBAC-UX destructive confirmation: PASS / N/A — the feature introduces no destructive actions. - RBAC-UX global search: PASS — touched resources either already have view pages or explicitly disable global search; the feature must not create new search dead ends. - Tenant isolation: PASS — tenant-owned references must enforce current tenant entitlement before exposing protected labels or links. - Run observability: PASS / N/A — existing `OperationRun` records may be displayed as resolved references, but no new run creation or lifecycle mutation occurs. - Ops-UX 3-surface feedback: PASS / N/A — no new operation-start or completion flow is introduced. - Ops-UX lifecycle and summary counts: PASS / N/A — no `OperationRun.status` or `OperationRun.outcome` transitions are introduced. - Ops-UX guards and system runs: PASS / N/A — existing operations behavior remains unchanged. - Automation: PASS / N/A — no queued or scheduled workflow changes are required. - Data minimization: PASS — reference presentation uses already-authorized labels, IDs, and source hints only; no secrets or raw payload dumps are introduced. - Badge semantics (BADGE-001): PASS — if reference-state badges are added or refined, they must map through `app/Support/Badges/BadgeCatalog.php` and `app/Support/Badges/BadgeRenderer.php` instead of page-specific label/color logic. - UI naming (UI-NAMING-001): PASS — operator-facing reference copy remains domain-first, such as “Policy,” “Baseline snapshot,” “Operation run,” “Group,” or “Role definition,” and technical ID terminology stays secondary. - UI naming (UI-NAMING-001): PASS — operator-facing reference copy remains domain-first, such as “Policy,” “Baseline snapshot,” “Operation run,” “Group,” or “Role definition,” and technical ID terminology stays secondary across labels, helper text, link labels, empty states, and degraded-state copy. - Filament UI Action Surface Contract: PASS — touched resources already expose list/view surfaces; the feature upgrades inspect affordances and related-context rows without introducing destructive or noisy action sprawl, and touched resources or relation managers must keep their `actionSurfaceDeclaration()` coverage current where applicable. - Filament UI UX-001: PASS — modified detail pages will continue to use sectioned infolists or read-only layouts, while list surfaces keep search/sort/filter behavior and adopt compact shared reference rendering. - Filament v5 / Livewire v4 compliance: PASS — the plan remains inside the existing Filament v5 / Livewire v4 application surfaces. - Provider registration (`bootstrap/providers.php`): PASS — no new panel provider is introduced; existing providers remain registered in `bootstrap/providers.php`. - Global search resource rule: PASS — `FindingResource`, `PolicyVersionResource`, `BackupSetResource`, and `EntraGroupResource` already have view pages; workspace-level resources touched by the feature that are not globally searchable remain disabled. - Asset strategy: PASS — no heavy frontend asset bundle is required; shared Blade partials and existing Filament assets are sufficient, and deploy-time `php artisan filament:assets` behavior remains unchanged. ## Project Structure ### Documentation (this feature) ```text specs/132-guid-context-resolver/ ├── plan.md ├── research.md ├── data-model.md ├── quickstart.md ├── contracts/ │ └── reference-presentation.openapi.yaml ├── checklists/ │ └── requirements.md └── tasks.md ``` ### Source Code (repository root) ```text app/ ├── Filament/ │ ├── Resources/ │ │ ├── FindingResource.php # existing related-context + list action consumer │ │ ├── PolicyVersionResource.php # existing related-context + policy lineage consumer │ │ ├── BackupSetResource.php # existing related-context + run linkage consumer │ │ ├── OperationRunResource.php # canonical run detail consumer │ │ ├── EntraGroupResource.php # current GUID-heavy directory reference surface │ │ ├── BaselineProfileResource/ │ │ │ └── RelationManagers/ │ │ │ └── BaselineTenantAssignmentsRelationManager.php # concrete assignment-like target surface │ │ └── BaselineSnapshotResource/ │ │ └── Pages/ViewBaselineSnapshot.php # snapshot detail related-context consumer │ └── Widgets/ │ └── Dashboard/ # reference-heavy summary surfaces to keep aligned later ├── Models/ │ ├── Policy.php │ ├── PolicyVersion.php │ ├── BaselineProfile.php │ ├── BaselineSnapshot.php │ ├── BackupSet.php │ ├── OperationRun.php │ ├── Finding.php │ ├── EntraGroup.php │ ├── EntraRoleDefinition.php │ └── Tenant.php ├── Services/ │ ├── Baselines/ │ │ └── SnapshotRendering/ # existing registry + DTO pattern to mirror │ └── Directory/ │ └── EntraGroupLabelResolver.php # existing narrow provider-backed label resolver ├── Support/ │ ├── Navigation/ │ │ ├── CrossResourceNavigationMatrix.php # existing source/surface matrix │ │ ├── RelatedNavigationResolver.php # existing entry-point to evolve or wrap │ │ ├── RelatedContextEntry.php # current shallow view payload model │ │ └── CanonicalNavigationContext.php # canonical link context helper │ ├── OperationRunLinks.php # canonical run route helper │ └── References/ # NEW shared reference descriptor/registry/value objects resources/ └── views/ └── filament/ └── infolists/ └── entries/ ├── related-context.blade.php # current reusable related-context renderer └── resolved-reference*.blade.php # NEW compact/detail variants tests/ ├── Feature/ │ ├── Filament/ # resource view/list rendering tests │ ├── Monitoring/ # canonical operations link tests │ └── Rbac/ # authorization-aware visibility/degradation tests └── Unit/ ├── Support/ │ └── References/ # NEW resolver registry / DTO / state tests └── Services/ └── Directory/ # existing label resolver tests that may be upgraded ``` **Structure Decision**: Keep the feature inside the existing Laravel/Filament monolith and extend the current shared navigation support rather than creating a parallel page-only solution. Introduce a dedicated reference-resolution layer under `app/Support/References`, then adapt the current `RelatedNavigationResolver`, related-context partials, and target resources to consume the richer reference semantics. ## Complexity Tracking > No Constitution Check violations. No justifications needed. | Violation | Why Needed | Simpler Alternative Rejected Because | |-----------|------------|-------------------------------------| | — | — | — | ## Phase 0 — Research (DONE) Output: - `specs/132-guid-context-resolver/research.md` Key findings captured: - The repo already has a first-generation shared navigation layer through `RelatedNavigationResolver`, `CrossResourceNavigationMatrix`, `RelatedContextEntry`, and the shared `related-context` Blade partial, but that layer models only availability plus links, not explicit descriptor classes, multi-state resolution, or controlled technical detail presentation. - `BaselineSnapshotPresenter`, `SnapshotTypeRendererRegistry`, and the rendered snapshot DTOs show a strong existing pattern for registry-driven resolution with immutable value objects and fallback behavior, which maps well to a shared reference resolver registry. - `EntraGroupLabelResolver` proves provider-backed label enrichment is already needed, but today it collapses unresolved and resolved references into a single label string instead of returning structured reference states. - `OperationRunLinks` and existing resource `getUrl()` helpers already encode canonical destinations, so Spec 132 should centralize richer label/state handling around those helpers instead of inventing new route families. - Filament v5 supports custom `ViewEntry` renderers and rich table layouts, so compact and detailed reference variants can remain shared without publishing internal Filament views or introducing a heavy frontend rewrite. - The highest-value target surfaces already expose related-context sections or reference-heavy infolist/table entries, making incremental adoption practical without a schema migration. ## Phase 1 — Design & Contracts (DONE) Outputs: - `specs/132-guid-context-resolver/data-model.md` - `specs/132-guid-context-resolver/contracts/reference-presentation.openapi.yaml` - `specs/132-guid-context-resolver/quickstart.md` Design highlights: - Introduce `ReferenceDescriptor`, `ResolvedReference`, `ReferenceLinkTarget`, `ReferenceTechnicalDetail`, `ReferencePresentationVariant`, and a `ReferenceResolverRegistry` as the canonical shared contracts for reference semantics. - Keep reference resolution DB-only and best-effort at render time by combining existing relations, local model lookups, stored source metadata, and narrow provider-backed label resolvers such as `EntraGroupLabelResolver`; no external provider call is allowed during page render. - Extend or wrap the current `RelatedNavigationResolver` so it produces richer reference payloads instead of today’s shallow `value + secondaryValue + availability` model. - Preserve canonical destinations through existing helpers like `OperationRunLinks` and resource `getUrl()` methods while making linkability capability-aware and non-ambiguous. - Add shared compact and detailed reference renderers so list rows and detail sections preserve the same semantic order even when the visual density differs, and map reference-state badges through the shared badge system. - Add shared compact and detailed reference renderers so list rows and detail sections preserve the same semantic order even when the visual density differs, map reference-state badges through the shared badge system, and preserve domain-consistent operator copy. - Roll out incrementally by first covering internal model-backed references, then security/provider-backed references, and finally upgrading existing related-context sections and table cells on the target surfaces. ## Phase 1 — Agent Context Update (DONE) Run: - `.specify/scripts/bash/update-agent-context.sh copilot` ## Phase 2 — Implementation Outline (tasks created in `/speckit.tasks`) ### Step 1 — Define the shared reference contracts and registry Goal: implement FR-132-02, FR-132-03, FR-132-05, FR-132-16, and FR-132-23. Changes: - Add the shared descriptor, state, technical-detail, and resolved-reference value objects. - Add a registry or dispatcher that maps explicit reference classes to concrete resolvers. - Define a fallback resolver for unsupported or unresolved classes that still keeps the reference visible. Tests: - Add unit coverage for registry dispatch, unsupported-class fallback, value-object normalization, and reference-state serialization. ### Step 2 — Implement the initial model-backed resolvers Goal: implement FR-132-01, FR-132-04, FR-132-09, FR-132-10, FR-132-13, and FR-132-21. Changes: - Add resolvers for policies, policy versions, baseline profiles, baseline snapshots, operation runs, and backup sets. - Resolve primary labels, type/context labels, canonical targets, and secondary technical details from local records and already-known relationships. - Batch or eager-load where needed so detail and list surfaces avoid N+1 lookups. Tests: - Add unit coverage for each core resolver, including resolved, partially resolved, missing, and unsupported cases. ### Step 3 — Implement governance, security, and provider-backed resolvers Goal: implement FR-132-04, FR-132-08, FR-132-10, FR-132-14, and FR-132-28. Changes: - Add resolvers for role definitions, Entra groups, principal-like references, assignment targets, and tenant-linked external object references that are already surfaced today. - Upgrade narrow helpers like `EntraGroupLabelResolver` into structured resolver collaborators instead of raw label string formatters. - Differentiate inaccessible, unresolved, deleted or missing, and external-only limited-context states explicitly. Tests: - Add unit coverage for provider-backed label reuse, inaccessible-state degradation, fallback labels, and deleted-object behavior. ### Step 4 — Create shared presentation variants and state vocabulary Goal: implement FR-132-06, FR-132-07, FR-132-08, FR-132-12, FR-132-18, FR-132-19, and FR-132-20. Changes: - Add compact and detailed shared reference renderers for infolists, related-context sections, and dense tables. - Keep the visual order consistent: label first, type/context second, state next, technical ID last. - Centralize state badges and unavailable-state copy instead of letting each resource improvise labels. Tests: - Add feature coverage proving technical IDs stay secondary, unresolved states remain visible, and clickable vs non-clickable rendering is unambiguous. ### Step 5 — Refactor target surfaces to consume the shared reference layer Goal: implement FR-132-15, FR-132-24, FR-132-25, FR-132-26, and FR-132-27. Changes: - Refactor findings, baseline snapshots, operation runs, policy versions, backup sets, the baseline tenant assignments relation manager, and assignment-evidence sections on finding, policy-version, and baseline-snapshot surfaces to use the shared resolver/presentation layer. - Replace GUID-heavy infolist/table fields and ad hoc related-context arrays with structured resolved references. - Ensure existing canonical links continue to flow through `OperationRunLinks` and resource route helpers while touched Filament resources preserve explicit inspect affordances, row-action caps, and documented exemptions. - Ensure tenant-context entry into canonical workspace destinations preserves visible originating-tenant meaning via filters, context badges, or source-context metadata where relevant. Tests: - Add or update Filament feature coverage for findings, baseline snapshots, operation runs, and assignment-like surfaces to prove label-first rendering and canonical links. ### Step 6 — Enforce authorization-aware degradation and regression safety Goal: implement FR-132-11, FR-132-14, FR-132-17, FR-132-22, and the acceptance criteria around safe degradation. Changes: - Ensure the shared layer differentiates non-member 404 semantics from in-scope capability denial and never leaks protected labels where policy forbids it. - Keep unsupported or partially known references visible without breaking pages. - Audit touched resources for remaining GUID-first output and remove page-specific formatting branches for supported classes. - Lock the rollout boundary so the surfaces named in the spec fully adopt the shared pattern now, while dashboard summary widgets and other out-of-scope views are explicitly allowed to remain on older formatting until a later spec. - Add regression coverage for domain-consistent operator copy and tenant-context carryover on migrated canonical destinations. Tests: - Add positive and negative authorization coverage proving inaccessible references are non-clickable, protected destinations stay guarded, and unsupported resolvers do not hide the underlying reference. - Add regression coverage preventing raw GUIDs from reappearing as the primary visible value on supported target surfaces. ## Constitution Check (Post-Design) Re-check result: PASS. - Livewire v4.0+ compliance: preserved because the design stays inside the existing Filament v5 / Livewire v4 surfaces. - Provider registration location: unchanged; existing panel providers remain registered in `bootstrap/providers.php`. - Globally searchable resources: touched searchable resources already expose view pages, and non-searchable resources remain explicitly disabled, so the Filament global-search rule remains satisfied. - Destructive actions: no new destructive actions are introduced; existing destructive behavior remains subject to current confirmation and authorization rules. - Asset strategy: no new heavy assets are introduced; shared Blade partials and existing Filament view infrastructure are sufficient, and deploy-time `php artisan filament:assets` behavior remains unchanged. - Testing plan: add focused Pest unit coverage for registry dispatch, resolver behavior, shared badge mapping, state normalization, and authorization-aware link generation, plus focused Filament feature coverage for findings, baseline snapshots, operation runs, the baseline tenant assignments relation manager, assignment-evidence surfaces, tenant-context carryover on canonical destinations, domain-consistent copy, and degraded-reference rendering.