# 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 | yes | Slot requirements and satisfied declarations | | `exemptions` | map | no | Explicit exemptions with reasons | | `metadata` | map | 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.