## Summary - add the complete Spec 196 artifact set for hard Filament nativity cleanup - include spec, requirements checklist, plan, research, data model, logical contract, quickstart, and executable tasks - update agent context after planning - resolve all cross-artifact consistency issues so the feature package is implementation-ready ## Included artifacts - specs/196-hard-filament-nativity-cleanup/spec.md - specs/196-hard-filament-nativity-cleanup/checklists/requirements.md - specs/196-hard-filament-nativity-cleanup/plan.md - specs/196-hard-filament-nativity-cleanup/research.md - specs/196-hard-filament-nativity-cleanup/data-model.md - specs/196-hard-filament-nativity-cleanup/contracts/filament-nativity-cleanup.logical.openapi.yaml - specs/196-hard-filament-nativity-cleanup/quickstart.md - specs/196-hard-filament-nativity-cleanup/tasks.md ## Notes - no runtime code paths were changed - no application tests were run because this change set is spec and planning documentation only - the artifact set was re-analyzed until no consistency issues remained Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #231
10 KiB
Data Model: Hard Filament Nativity Cleanup
Overview
This feature introduces no new persisted entity, table, enum, or product-domain source of truth. It refactors three existing UI surfaces by replacing pseudo-native interaction contracts with native page-owned or component-owned state.
The data model for planning is therefore a set of derived UI-state and row-projection models that answer four questions:
- What state is authoritative for each cleaned surface?
- Which source truths continue to produce the rows and summaries?
- Which values may be seeded from deeplinks, and which values must remain route- or entitlement-authoritative?
- Which invariants must remain true after the cleanup?
Existing Source Truths Reused Without Change
The following truths remain authoritative and are not redefined by this feature:
InventoryItem,InventoryLink,DependencyQueryService, andDependencyTargetResolverfor dependency edges and rendered targets- the current tenant-context inventory route and inventory-record scope rules
TenantRequiredPermissionsViewModelBuilder,TenantPermission, permission configuration, and provider guidance links for required-permissions truth- the route-scoped tenant on
/admin/tenants/{tenant:external_id}/required-permissions EvidenceSnapshot,TenantReview,ArtifactTruthPresenter, and the current workspace-context entitlement rules for evidence overview rows- existing capability registries,
WorkspaceContext, tenant membership checks, and current deny-as-not-found boundaries
This feature changes how these truths are controlled and rendered, not what they mean.
New Derived Planning Models
DependencyEdgesTableState
Type: embedded detail-surface state
Source: Livewire component state on inventory item detail
| Field | Type | Notes |
|---|---|---|
inventoryItemId |
int | Required current detail record key |
tenantId |
int | Required tenant-context key derived from the current panel or record scope |
direction |
string | Allowed values: all, inbound, outbound; default all |
relationshipType |
string or null | Null means all relationship types; otherwise one allowed relationship type key |
Validation rules
inventoryItemIdmust resolve to the current authorized record.tenantIdmust match the current tenant-context scope.directionmust stay inside the three allowed values.relationshipTypemust be null or a recognized relationship type value.
DependencyEdgeRow
Type: derived row projection
Source: DependencyQueryService plus DependencyTargetResolver
| Field | Type | Notes |
|---|---|---|
relationshipType |
string | Canonical relationship family for grouping or filter matching |
targetType |
string | Current target kind, including missing when unresolved |
targetId |
string or null | External or internal target identifier |
renderedTarget |
array | Existing rendered badge and link payload |
isMissing |
boolean | Derived from targetType === missing |
missingTitle |
string | Existing descriptive fallback text for unresolved targets |
Invariants
- Row membership must stay tenant-isolated.
- Missing-target rendering must preserve current operator hints.
- Render-time behavior must remain DB-only with no Graph access.
RequiredPermissionsTableState
Type: page-owned derived table state
Source: native Filament table filters and search on TenantRequiredPermissions
| Field | Type | Notes |
|---|---|---|
routeTenantExternalId |
string | Authoritative tenant scope from the route |
status |
string | Allowed values: missing, present, error, all |
type |
string | Allowed values: all, application, delegated |
features |
list | Zero or more selected feature keys |
search |
string | Native table search text |
seededFromQuery |
boolean | True only during initial mount when deeplink values were present |
Validation rules
- The route tenant always wins over tenant-like query values.
- Query values may seed
status,type,features, andsearchonly at initial mount. featuresmust be a normalized unique list of known feature keys.
RequiredPermissionsSummaryProjection
Type: derived page summary model
Source: TenantRequiredPermissionsViewModelBuilder evaluated against the currently active normalized filter state
| Field | Type | Notes |
|---|---|---|
counts |
object | Existing counts for missing application, missing delegated, present, and error rows |
overall |
string or null | Existing overall readiness state |
freshness |
object | Existing freshness payload including stale or not stale |
featureImpacts |
list | Existing per-feature impact summary |
copyPayloads |
object | Existing application and delegated copy payloads |
issues |
list | Existing derived guidance and next-step content |
Invariants
- Summary and table rows must be derived from the same active filter state.
- Copy payload semantics must remain consistent with current expectations.
- Tenant scope must not be mutable through filter state.
PermissionReviewRow
Type: derived table row
Source: TenantRequiredPermissionsViewModelBuilder
| Field | Type | Notes |
|---|---|---|
permissionKey |
string | Stable permission identifier |
type |
string | application or delegated |
status |
string | Current permission review status |
description |
string | Human-readable permission description |
features |
list | Feature tags associated with the permission |
details |
object | Existing supporting metadata used for inline review only |
EvidenceOverviewTableState
Type: workspace-context table state
Source: native Filament table search and optional query-seeded entitled tenant prefilter
| Field | Type | Notes |
|---|---|---|
workspaceId |
int | Required current workspace context |
authorizedTenantIds |
list | Entitled tenant ids available to the actor |
tenantFilter |
int or null | Current entitled tenant prefilter, nullable when not active |
search |
string | Native table search across tenant-facing row labels |
seededFromQuery |
boolean | True only when the initial request carried a prefilter |
Validation rules
tenantFiltermust be null or one of the actor's entitled tenant ids.- Missing workspace membership continues to produce
404. - Non-entitled tenant ids must not leak through filter state, row counts, or drilldowns.
EvidenceOverviewRow
Type: derived workspace report row
Source: current snapshot query plus ArtifactTruthPresenter
| Field | Type | Notes |
|---|---|---|
tenantId |
int | Entitled tenant identifier |
tenantName |
string | Current display label |
snapshotId |
int | Current active snapshot id for drilldown |
artifactTruth |
object | Existing truth badge and explanation payload |
freshness |
object | Existing freshness badge payload |
generatedAt |
string or null | Timestamp label |
missingDimensions |
int | Existing burden metric |
staleDimensions |
int | Existing burden metric |
nextStep |
string | Existing next-step text |
viewUrl |
string | Current tenant evidence drilldown URL |
Invariants
- Row drilldowns must stay workspace-safe and tenant-entitlement-safe.
- Derived-state memoization must remain effective.
- Render-time behavior must remain DB-only.
CleanupAdmissionCandidate
Type: planning-only admission check
Source: implementation audit only when a possible extra hit is discovered
| Field | Type | Notes |
|---|---|---|
surfaceKey |
string | Stable human-readable identifier |
path |
string | File or route path for the potential extra surface |
matchesProblemClass |
boolean | Must be true to qualify |
opensArchitectureQuestion |
boolean | Must be false to qualify |
decision |
string | include or defer |
reason |
string | Explicit justification for the decision |
State Transition Rules
Rule 1 - Deeplink seed to native active state
- Initial request query values may seed filter state on
TenantRequiredPermissionsandEvidenceOverview. - After initial mount, active state belongs to the native page table or component, not to
request().
Rule 2 - Route scope remains authoritative
TenantRequiredPermissionsmay never replace its route tenant from query values.- Inventory dependency state may never replace the current detail record or tenant context.
- Evidence overview may never reveal non-entitled tenant rows through a prefilter.
Rule 3 - No new persistence or mirrored helper truth
- Filter state stays session-backed or Livewire-backed only where Filament already provides that behavior.
- No new database table, JSON helper artifact, or persisted UI-state mirror is introduced.
Safety Rules
- No cleaned surface may introduce a second wrapper contract that simply restyles the current non-native behavior.
- No cleaned surface may widen current workspace or tenant scope behavior.
- No cleaned surface may lose current empty-state meaning, next-step clarity, or inspect destination correctness.
- No page or component may call Graph or other remote APIs during render as part of this cleanup.
Planned Test Mapping
| Model / Rule | Existing Coverage | Planned Additions |
|---|---|---|
DependencyEdgesTableState |
tests/Feature/InventoryItemDependenciesTest.php, dependency tenant-isolation and query-service tests |
native component test for direction and relationship interaction |
RequiredPermissionsTableState |
tests/Feature/Rbac/TenantRequiredPermissionsTrustedStateTest.php, unit filter normalization tests |
page-level native table test |
RequiredPermissionsSummaryProjection |
current unit tests for freshness, overall state, feature impacts, and copy payloads | page-level summary consistency assertions |
EvidenceOverviewTableState |
tests/Feature/Evidence/EvidenceOverviewPageTest.php |
native table assertions and any new table-standard guard alignment |
EvidenceOverviewRow DB-only invariant |
tests/Feature/Filament/EvidenceOverviewDerivedStateMemoizationTest.php |
update assertions to reflect native table rendering without losing memoization guarantees |