6.7 KiB
Data Model: Livewire Context Locking and Trusted-State Reduction
This feature does not introduce new database tables in the first slice. The data-model work formalizes trust-boundary entities and field classes that are already implicit in existing Livewire and Filament components.
1. Trusted State Class
Purpose
Defines how a given piece of component state may be stored and used.
Allowed values
presentationlocked_identityserver_derived_authority
Rules
presentationstate may remain public and mutable.locked_identitystate may remain public only when it is client-immutable and still re-resolved before protected actions.server_derived_authoritystate must not rely on client mutability at all and is derived from route, session, resolver, or persisted workflow truth.
2. Component Trusted-State Policy
Purpose
Represents the trust contract for one stateful Livewire or Filament surface.
Fields
component_name: human-readable identifier for the surfaceplane:admin_tenant,admin_workspace, orsystem_platformroute_anchor: route-bound record or context source, if anyauthority_sources: canonical sources used to re-derive protected targetslocked_identities: list of public scalar IDs allowed to persist for continuitymutable_selectors: list of user-controlled selectors that remain proposals onlyforbidden_public_authority_fields: list of model objects or mutable IDs disallowed as final authority
Relationships
- One component policy has many trusted fields.
- One component policy has many forged-state regression cases.
3. Trusted Field
Purpose
Represents one public property or equivalent state slot on a covered component.
Fields
field_namestate_classphp_typesource_of_truthused_for_protected_action: booleanrevalidation_required: booleannotes
Validation rules
- If
state_class = presentation, thenused_for_protected_actionmust be false. - If
used_for_protected_action = true, thenstate_classmust belocked_identityorserver_derived_authority. - If
php_typeis an Eloquent model and the field is ownership-relevant, it is a migration target and should be phased toward locked scalar or server-derived access.
4. Authority Source
Purpose
Represents the canonical seam used to re-derive truth on the server.
First-slice source types
route_bindingworkspace_contexttenant_panel_contextpersisted_onboarding_draftallowed_tenant_universeexplicit_scoped_query
Example mappings
- Onboarding draft identity: route binding + persisted onboarding draft
- Current workspace:
WorkspaceContext - Tenant-context page scope: route binding or
ResolvesPanelTenantContext - System runbook tenant selector:
AllowedTenantUniverse
5. Selector Proposal
Purpose
Represents mutable client-submitted selection state that is allowed to change but must be validated before use.
Fields
selector_nametarget_modelscope_rulesnull_allowed: booleanvalidation_outcome
Validation outcomes
acceptedrejected_not_foundrejected_forbiddenreset_required
Rules
- A selector proposal never grants authority by itself.
- A selector proposal must be re-scoped to the current workspace, tenant, or allowed-universe before action execution.
6. Forged-State Regression Case
Purpose
Represents a reproducible test scenario where client state is mutated to challenge the trust boundary.
Fields
component_namemutation_type:foreign_id,stale_id,null_forced,cross_workspace,cross_planeentry_point: page load, action call, modal submit, or rerun pathexpected_outcome:404,403, or no-op fail-closedmust_preserve_data_integrity: boolean
State transitions
pending_design→covered_by_testcovered_by_test→guarded_in_ci
7. First-Slice Surface Inventory
Managed Tenant Onboarding Wizard
route_anchor: onboarding draft route parameter- Locked identities:
managedTenantId(?int) backed by persisted onboarding draft identity and re-resolved throughcurrentManagedTenantRecord()onboardingSessionId(?int) backed by persisted onboarding draft identity and re-resolved throughcurrentOnboardingSessionRecord()
- Mutable selector proposals:
selectedProviderConnectionId(?int) revalidated against canonical draft and scoped provider queries before verify/bootstrap pathsselectedBootstrapOperationTypes(array<int, string>) remains presentation-only wizard state
- Server-derived authority fields:
- public
Workspace $workspacerefreshed fromWorkspaceContext - public
?Tenant $managedTenanttreated as display convenience only; canonical tenant truth comes from draft/scoped query - public
?TenantOnboardingSession $onboardingSessiontreated as display convenience only; canonical draft truth comes from resolver-backed persisted session lookup
- public
- Canonical authority sources:
WorkspaceContext- onboarding draft resolver
- persisted draft state
- scoped provider-connection query
Tenant Required Permissions Page
route_anchor: tenant route parameter- Locked identities:
scopedTenantId(?int) derived from the route tenant and revalidated throughtrustedScopedTenant()
- Mutable selector proposals:
status,type,features, andsearchremain presentation-only filters
- Server-derived authority fields:
- canonical tenant scope is derived through
resolveScopedTenant(),WorkspaceContext, andtrustedScopedTenant()
- canonical tenant scope is derived through
- Canonical authority sources:
- route-bound tenant resolution
- workspace context
System Runbooks Page
route_anchor: none- Locked identities:
- none in the first slice; platform selector state remains proposal-only
- Public selector proposals:
findingsTenantId(?int) is revalidated throughAllowedTenantUniverse::resolveAllowedOrFail()tenantId(?int) is mirrored display state for the last trusted preflight resultfindingsScopeModeandscopeModeremain mutable UI state that must normalize into a trusted scope DTO before action execution
- Server-derived authority fields:
- trusted scope derives from
trustedFindingsScopeFromFormData()/trustedFindingsScopeFromState()and the allowed tenant universe
- trusted scope derives from
- Canonical authority sources:
- authenticated platform user
- allowed tenant universe
- runbook scope DTO
8. Out-of-Scope but Related Fields
- Public widget record models such as tenant widgets storing
public ?Tenant $record - Resource page state handled primarily through Filament route model binding
- Non-stateful controller endpoints and queued job payloads
These remain rollout inventory candidates after the first slice proves the trusted-state pattern.