## Summary - implement the Action Surface Contract v1.1 runtime changes for Spec 169 - add the new explicit ActionSurfaceType contract, validator/discovery updates, and enrolled surface declarations - update Filament action-surface documentation, focused guard tests, and spec artifacts for the completed feature ## Included - clickable-row vs explicit-inspect enforcement across monitoring, reporting, CRUD, and system reference surfaces - helper-first, workflow-next, destructive-last overflow ordering checks - system panel list discovery in the primary action-surface validator - Spec 169 artifacts: spec, plan, tasks, research, data model, quickstart, and logical contract ## Verification - focused Pest verification pack completed for: - tests/Feature/Guards/ActionSurfaceValidatorTest.php - tests/Feature/Guards/ActionSurfaceContractTest.php - tests/Feature/Rbac/TenantActionSurfaceConsistencyTest.php - integrated browser smoke test completed for admin-side reference surfaces: - /admin/operations - /admin/audit-log - /admin/finding-exceptions/queue - /admin/reviews - /admin/tenants ## Notes - system panel browser smoke coverage could not be exercised in the same session because /system routes require platform authentication in the integrated browser - Livewire target remains v4-compliant and no provider registration or asset strategy changes are introduced by this PR Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #200
195 lines
9.3 KiB
Markdown
195 lines
9.3 KiB
Markdown
# Phase 1 Data Model: Action Surface Contract v1.1
|
||
|
||
## Overview
|
||
|
||
This feature does not add a database table, persisted artifact, or cache. It extends the existing runtime action-surface contract with one new declaration-level enum and codifies the derived rules that govern discovery, inspect behavior, and overflow ordering for the enrolled reference surfaces.
|
||
|
||
## Existing Runtime Source Objects
|
||
|
||
### ActionSurfaceDeclaration v1.0
|
||
|
||
**Purpose**: Existing declaration object used by Resources, Pages, and RelationManagers to describe action-surface requirements.
|
||
|
||
**Current fields**:
|
||
- `version`
|
||
- `componentType`
|
||
- `profile`
|
||
- `defaults`
|
||
- `slots`
|
||
- `exemptions`
|
||
- `metadata`
|
||
|
||
**Current behavior**:
|
||
- Declares slot satisfaction or exemption.
|
||
- Stores ad hoc metadata such as list row primary action limit.
|
||
- Does not currently encode constitution surface type explicitly.
|
||
|
||
### ActionSurfaceProfile
|
||
|
||
**Purpose**: Existing slot-requirement family used by `ActionSurfaceProfileDefinition`.
|
||
|
||
**Current values**:
|
||
- `CrudListAndEdit`
|
||
- `CrudListAndView`
|
||
- `ListOnlyReadOnly`
|
||
- `RunLog`
|
||
- `RelationManager`
|
||
|
||
**Validation role**:
|
||
- Drives which slots are required.
|
||
- Does not safely express whether a surface must be clickable-row, explicit-inspect, or edit-as-inspect.
|
||
|
||
### ActionSurfaceDiscovery and ActionSurfaceDiscoveredComponent
|
||
|
||
**Purpose**: Discover the repository’s in-scope declaration-backed components and pass them to the validator.
|
||
|
||
**Current fields on discovered component**:
|
||
- `className`
|
||
- `componentType`
|
||
- `panelScopes`
|
||
|
||
**Current limitation**:
|
||
- The main discovery pass covers declaration-backed tenant/admin surfaces but still excludes the enrolled system-panel list pages and cannot yet enforce the constitution behavior split precisely enough on the reference surfaces.
|
||
|
||
### ActionSurfaceValidationIssue and ActionSurfaceValidationResult
|
||
|
||
**Purpose**: Existing validator output used by the guard suite.
|
||
|
||
**Current role**:
|
||
- Reports missing declarations, missing required slots, invalid inspect-affordance tokens, missing exemption reasons, and invalid read-only export defaults.
|
||
|
||
## New Runtime Entities
|
||
|
||
### ActionSurfaceType
|
||
|
||
**Purpose**: First-class constitution-aligned behavioral classification used to determine the allowed primary inspect model for a surface.
|
||
|
||
#### Values
|
||
|
||
| Value | Description | Allowed primary inspect model |
|
||
|-------|-------------|-------------------------------|
|
||
| `CrudListFirstResource` | Standard list-first CRUD resource where open and mutate decisions happen after entering the record | Clickable row by default; `PrimaryLinkColumn` only with explicit reason |
|
||
| `ReadOnlyRegistryReport` | Scan-first registry or report surface with read-mostly or immutable records | Clickable row by default; `PrimaryLinkColumn` only with explicit reason |
|
||
| `QueueReview` | Queue where the operator reviews an item in context and continues the queue | Explicit inspect / same-page selected detail; row click forbidden by default |
|
||
| `HistoryAudit` | Immutable history or audit surface where chronology and context must be preserved | Explicit inspect / same-page selected detail; row click forbidden by default |
|
||
| `ConfigLite` | Low-cardinality configuration where edit is the primary inspect surface | Edit-as-inspect allowed by default; no parallel View surface |
|
||
|
||
#### Validation rules
|
||
|
||
- Every declaration-backed component enrolled in the v1.1 reference pack must declare one `ActionSurfaceType`.
|
||
- `ActionSurfaceType` determines inspect-model compatibility; `ActionSurfaceProfile` continues to determine required slots.
|
||
- `PrimaryLinkColumn` is valid only when a concrete reason explains why row click is not the correct primary inspect model.
|
||
|
||
### ActionSurfaceDeclaration v1.1
|
||
|
||
**Purpose**: Extended declaration contract that combines slot requirements with explicit constitution behavior.
|
||
|
||
#### Fields
|
||
|
||
| Field | Type | Required | Description |
|
||
|-------|------|----------|-------------|
|
||
| `version` | int | yes | Contract version |
|
||
| `componentType` | enum | yes | Resource, Page, or RelationManager |
|
||
| `profile` | `ActionSurfaceProfile` | yes | Existing slot-requirement family |
|
||
| `surfaceType` | `ActionSurfaceType` | yes | New constitution-aligned behavior family |
|
||
| `defaults` | `ActionSurfaceDefaults` | yes | Shared defaults such as `moreGroupLabel` |
|
||
| `slots` | map<ActionSurfaceSlot, ActionSurfaceSlotRequirement> | yes | Slot requirements and satisfied declarations |
|
||
| `exemptions` | map<ActionSurfaceSlot, ActionSurfaceExemption> | no | Explicit exemptions with reasons |
|
||
| `metadata` | map<string, mixed> | no | Existing narrow metadata storage |
|
||
| `listRowPrimaryActionLimit` | int nullable | no | Existing row-action budget metadata |
|
||
| `primaryLinkColumnReason` | string nullable | no | Required when the inspect affordance is `PrimaryLinkColumn` |
|
||
|
||
#### Relationships
|
||
|
||
- One declaration belongs to exactly one component class.
|
||
- One declaration has exactly one `ActionSurfaceProfile` and one `ActionSurfaceType`.
|
||
- One declaration contains many slot requirements and optional slot exemptions.
|
||
|
||
#### Validation rules
|
||
|
||
- `surfaceType` is required for all components inside the v1.1 primary discovery scope.
|
||
- `surfaceType` and `InspectAffordance` must be compatible.
|
||
- `defaults.moreGroupLabel` must remain `More`.
|
||
- Empty or reasonless exemptions remain invalid.
|
||
|
||
### InspectDecisionRule
|
||
|
||
**Purpose**: Derived rule family that maps `surfaceType` to allowed inspect behavior.
|
||
|
||
#### Fields
|
||
|
||
| Field | Type | Required | Description |
|
||
|-------|------|----------|-------------|
|
||
| `surfaceType` | `ActionSurfaceType` | yes | Surface family being governed |
|
||
| `allowedAffordances` | list<`ActionSurfaceInspectAffordance`> | yes | Allowed inspect affordance values |
|
||
| `forbiddenRedundantView` | bool | yes | Whether a lone row `View` action is forbidden |
|
||
| `requiresPrimaryLinkReason` | bool | yes | Whether `PrimaryLinkColumn` must include a concrete reason |
|
||
|
||
#### Validation rules
|
||
|
||
- CRUD and registry surfaces must expose one obvious open path and may not render a redundant lone `View` row action.
|
||
- Queue and audit surfaces must preserve context through explicit inspect.
|
||
- Config-lite surfaces may open edit as inspect but may not add a competing View surface.
|
||
|
||
### ActionOrderingRule
|
||
|
||
**Purpose**: Derived rule family that governs `ActionGroup` and `BulkActionGroup` content on governed surfaces.
|
||
|
||
#### Fields
|
||
|
||
| Field | Type | Required | Description |
|
||
|-------|------|----------|-------------|
|
||
| `groupLabel` | string | yes | Must remain `More` for governed overflow groups |
|
||
| `inspectionHelpersFirst` | bool | yes | Navigation and safe inspection helpers come first |
|
||
| `workflowAfterNavigation` | bool | yes | Non-destructive lifecycle and workflow actions follow safe helpers |
|
||
| `destructiveLast` | bool | yes | Destructive actions sort last |
|
||
| `emptyGroupForbidden` | bool | yes | Empty `ActionGroup` and `BulkActionGroup` placeholders are invalid |
|
||
|
||
#### Validation rules
|
||
|
||
- Overflow groups must not exist only as placeholders.
|
||
- Inspection and navigation helpers must lead the group when present.
|
||
- Non-destructive lifecycle and workflow actions must follow safe helpers and must not trail destructive actions.
|
||
- Destructive actions must sort last.
|
||
- Ordering checks are enforced through representative rendered guard tests rather than generic runtime reflection across every surface.
|
||
|
||
### PrimaryDiscoveryScope
|
||
|
||
**Purpose**: Defines which repository surfaces the primary validator must discover.
|
||
|
||
#### Included families
|
||
|
||
- Enrolled monitoring and reporting pages under `app/Filament/Pages/**`
|
||
- Enrolled representative CRUD and read-only registry resources under `app/Filament/Resources/**`
|
||
- Declared, table-backed pages under `app/Filament/System/Pages/**` for the six enrolled system list surfaces
|
||
|
||
#### Excluded families
|
||
|
||
- Widgets
|
||
- Auth pages
|
||
- Dashboards
|
||
- Choosers and onboarding wizards
|
||
- Deferred or non-table system tooling such as Runbooks
|
||
- Any class kept under explicit baseline exemption until a later spec enrolls it
|
||
|
||
#### Validation rules
|
||
|
||
- Discovery must not require new baseline exemptions for already enrolled system pages.
|
||
- Out-of-scope families must remain explicitly excluded rather than silently swept in.
|
||
|
||
## Representative Surface Mapping
|
||
|
||
| Surface | Profile | Surface type | Inspect affordance | Ordering anchor |
|
||
|---------|---------|--------------|--------------------|-----------------|
|
||
| `Monitoring/Operations` | `RunLog` | `ReadOnlyRegistryReport` | `ClickableRow` | No row actions; row click is the anchor |
|
||
| `Monitoring/AuditLog` | `RunLog` | `HistoryAudit` | Explicit inspect | No row click; context-preserving inspect is the anchor |
|
||
| `Monitoring/FindingExceptionsQueue` | `RunLog` | `QueueReview` | Explicit inspect | Selected-record workflow actions stay off the standard list row |
|
||
| `BaselineProfileResource` | `CrudListAndView` | `CrudListFirstResource` | `ClickableRow` | `More` contains safe actions first and archive last |
|
||
| `System/Ops/Runs` | `RunLog` | `ReadOnlyRegistryReport` | `ClickableRow` to canonical system run detail | Cross-panel registry coverage anchor that preserves the canonical `Operations / Run` noun |
|
||
| `System/Security/AccessLogs` | `RunLog` | `HistoryAudit` | Explicit inspect | System audit reference anchor |
|
||
|
||
## Migration Notes
|
||
|
||
- No schema migration is required.
|
||
- No new queue, notification, or asset behavior is introduced.
|
||
- The final validator state requires explicit `surfaceType` on every discovered declaration-backed surface. |