TenantAtlas/specs/169-action-surface-v11/spec.md

222 lines
37 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Feature Specification: Action Surface Contract v1.1: Inspect Decision Rules, Menu Ordering, and Behavior Guard Coverage
**Feature Branch**: `169-action-surface-v11`
**Created**: 2026-03-30
**Status**: Draft
**Input**: User description: "Spec 169 — Action Surface Contract v1.1: Inspect Rules, Menu Ordering, and System Guard Coverage"
## Clarifications
### Session 2026-03-30
- Q: How should Spec 169 require the contract to encode surface type for enforcement? → A: Add a first-class declaration field / enum for constitution surface types and drive inspect-rule enforcement from it.
## Spec Scope Fields *(mandatory)*
- **Scope**: workspace + tenant + canonical-view + platform
- **Primary Routes**:
- `/admin/operations` and `/admin/operations/{run}` for the canonical operations list and run detail flow that now represent the clickable-row reference implementation
- `/admin/audit-log` for the history / audit surface that intentionally uses explicit inspect rather than row navigation
- `/admin/finding-exceptions/queue` for the queue / review surface that intentionally uses explicit inspect and selected-record detail actions
- `/system/ops/runs`, `/system/ops/failures`, and `/system/ops/stuck` for system-panel operational list surfaces that must be discovered by the primary contract guard
- `/system/directory/tenants`, `/system/directory/workspaces`, and `/system/security/access-logs` for system-panel registry and audit list surfaces that must be discovered by the primary contract guard
- existing CRUD / List-first resource surfaces that already declare the contract, especially the Tenants and Policies lists, as representative ordering-rule references rather than new rollout targets
- **Data Ownership**:
- No tenant-owned or workspace-owned business entity changes are introduced
- The only structural surface owned by this feature is the in-code action-surface declaration and validator contract, plus the supporting standards documentation and guard tests that govern operator-facing list behavior
- Existing tenant-owned, workspace-owned, and platform-owned records remain unchanged; this feature only governs how their list surfaces declare and enforce interaction semantics
- **RBAC**:
- Existing tenant/admin and platform authorization planes remain unchanged
- Existing workspace membership, tenant entitlement, and platform capability checks remain the enforcement source for covered pages
- Non-members or cross-plane actors remain deny-as-not-found; in-scope members without capability remain forbidden
- This feature must not weaken or bypass existing server-side authorization and must not treat UI contract enforcement as a security boundary
For canonical-view specs, the spec MUST define:
- **Default filter behavior when tenant-context is active**: Canonical and workspace-scoped list pages keep their current tenant-prefilter behavior when entered from tenant context. This feature does not broaden filter scope; it only governs inspect/open behavior and action ordering on those surfaces.
- **Explicit entitlement checks preventing cross-tenant leakage**: Existing tenant and workspace entitlement checks remain authoritative. Adding system-panel pages to the primary discovery and validation pass must not alter route visibility, record visibility, or link generation rules. Contract discovery must never imply broader access.
## UI/UX Surface Classification *(mandatory when operator-facing surfaces are changed)*
| Surface | Surface Type | Primary Inspect/Open Model | Row Click | Secondary Actions Placement | Destructive Actions Placement | Canonical Collection Route | Canonical Detail Route | Scope Signals | Canonical Noun | Critical Truth Visible by Default | Exception Type |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Monitoring Operations | Read-only Registry / Report | Full-row click to canonical run detail | required | none on the list; related actions live on the detail header | none on the list; any dangerous follow-up remains on the detail header | `/admin/operations` | `/admin/operations/{run}` | Workspace scope plus optional tenant filter | Operations / Run | run status, outcome, age, initiator | none |
| Monitoring Audit Log | History / Audit | Explicit Inspect action with same-page selected-event detail | forbidden | page header and selected-event header actions | none on the list; no destructive audit-row action | `/admin/audit-log` | `/admin/audit-log?event={event}` | Workspace scope plus tenant filter | Audit log / Audit event | outcome, actor, target, recorded time | none |
| Finding Exceptions Queue | Queue / Review | Explicit Inspect action with same-page selected-record review detail | forbidden | page header and selected-record header actions | selected-record header only; list rows stay decision-light | `/admin/finding-exceptions/queue` | `/admin/finding-exceptions/queue?exception={record}` | Workspace scope plus tenant prefilter when entered from tenant context | Finding exceptions / Exception | approval state, tenant, requested governance action, expiry urgency | none |
| Reporting and evidence registers (`Review Register`, `Evidence Overview`) | Read-only Registry / Report | Full-row click to the existing review or evidence detail destination | required | filter-reset or scope-reset helpers remain in the page header; no row-level secondary actions | none on the list | `/admin/reviews` and the existing evidence overview route | existing tenant-scoped review and evidence detail destinations | Workspace scope plus optional tenant filter or prefilter context | Reviews / Review and Evidence / Snapshot | artifact truth, completeness or freshness, generated or captured time | none |
| System operations lists (`Runs`, `Failures`, `Stuck`) | Read-only Registry / Report | Full-row click to system run detail | required | none on the list unless a system page has a justified secondary action | none on the list | `/system/ops/runs`, `/system/ops/failures`, `/system/ops/stuck` | `/system/ops/{run}` | Platform scope only | Operations / Run | run status, outcome, recency, failure/stuck signal | Cross-panel Canonical Route Exception |
| System directory lists (`Tenants`, `Workspaces`) | Read-only Registry / Report | Full-row click to system entity detail | required | none on the list unless a page-specific safe shortcut is justified | none on the list | `/system/directory/tenants`, `/system/directory/workspaces` | existing system detail pages for tenant/workspace inspection | Platform scope only | Tenants / Workspaces | identity, state, summary metadata needed for selection | none |
| System access logs | History / Audit | Explicit Inspect action or equivalent context-preserving detail open | forbidden by default | page header and selected-record context actions | none on the list | `/system/security/access-logs` | same-page selected detail or existing system detail route | Platform scope only | Access logs / Access event | actor, capability, outcome, recorded time | none |
| Representative read-only registry resources (`Operation runs`, `Alert deliveries`, `Baseline snapshots`, `Evidence snapshots`, `Review packs`, `Tenant reviews`) | Read-only Registry / Report | One-click open only, normally via row click, with at most one justified non-destructive inline shortcut | required unless a documented exception applies | no row secondary actions by default; any justified safe shortcut remains singular | detail header only, or `More` only where an existing lifecycle action already exists | existing tenant or workspace collection routes | existing view routes | existing tenant or workspace scope chips remain truthful | resource-specific canonical noun remains stable per resource | outcome, freshness, completeness, publication readiness, or artifact truth required for triage | none |
| Representative CRUD list-first resources (`Tenants`, `Policies`, `Baseline profiles`, `Backup schedules`, `Workspaces`) | CRUD / List-first Resource | One-click open only, with at most one inline safe shortcut when justified | required unless a documented exception applies | one inline safe shortcut plus `More` | `More` and detail header only | existing tenant/admin collection routes | existing view or edit routes | Workspace or tenant context chips already in use | resource-specific canonical nouns such as Tenants / Tenant, Policies / Policy, Baselines / Baseline, Backup schedules / Backup schedule, and Workspaces / Workspace | lifecycle, operability, status needed for action | none |
## Operator Surface Contract *(mandatory when operator-facing surfaces are changed)*
| Surface | Primary Persona | Surface Type | Primary Operator Question | Default-visible Information | Diagnostics-only Information | Status Dimensions Used | Mutation Scope | Primary Actions | Dangerous Actions |
|---|---|---|---|---|---|---|---|---|---|
| Monitoring Operations | Tenant operator or workspace operator | Read-only Registry / Report | Which runs should I open, and what happened most recently? | status, outcome, operation type, initiator, start time, duration | raw context JSON, normalized counts, internal IDs, related diagnostic payloads | execution outcome, lifecycle recency | Read-only list; existing detail actions unchanged | Open run | Existing detail-level retry or resume actions only where already allowed |
| Monitoring Audit Log | Senior operator or auditor | History / Audit | Which event should I inspect without losing chronology? | outcome, actor, action, target, recorded time | full metadata payload, deeper trace context, internal identifiers | audit outcome, chronology | Read-only | Inspect event, open related record | none |
| Finding Exceptions Queue | Workspace approver or governance reviewer | Queue / Review | Which exception needs review now, and what is the right decision? | approval state, tenant, target finding, expiry or urgency, requester context | full request details, governance history, supporting raw metadata | approval lifecycle, urgency | Existing approve/reject workflow only | Inspect exception, approve, reject, open related finding | Approve/reject remain selected-detail actions with existing confirmation and authorization |
| Reporting and evidence registers | Workspace operator, reviewer, or auditor | Read-only Registry / Report | Which review or evidence record should I open next without losing scanability? | artifact truth, completeness or freshness, generated or captured time, tenant context when applicable | raw JSON, detailed supporting payloads, internal identifiers | artifact freshness, completeness, publication readiness where applicable | Read-only | Open review or evidence detail | none |
| System operations lists | Platform operator | Read-only Registry / Report | Which platform operation or failure needs investigation? | run type, status, outcome, recency, high-signal failure context | raw run payloads, internal run metadata, technical traces | execution outcome, chronology, stuck or failed state | Read-only list; existing run follow-up unchanged | Open run | Existing run follow-up actions only where already defined |
| System directory lists | Platform operator | Read-only Registry / Report | Which platform record do I need to inspect next? | name, identity, high-signal summary metadata | deeper system metadata and internal diagnostic fields | lifecycle or availability where relevant | Read-only | Open detail | none |
| Representative read-only registry resources | Tenant or workspace operator | Read-only Registry / Report | Which immutable or read-mostly record should I open next? | artifact truth, freshness, completeness, outcome, or publication readiness needed for triage | raw JSON, related payloads, deep diagnostics, internal identifiers | resource-specific truth dimensions remain separate | Read-only or tightly scoped lifecycle follow-up only | Open detail, with at most one justified safe shortcut | Existing lifecycle cleanup remains detail-header first, or `More` only where already present |
| Representative CRUD resources | Tenant or workspace operator | CRUD / List-first Resource | Which record should I open or mutate next? | identifier, health, operability, lifecycle or status needed for triage | raw IDs, low-level diagnostics, provider payload details | lifecycle, operability, state | Existing resource mutations only | Open record, one justified inline safe shortcut | Existing destructive actions remain under `More` or detail header |
## Proportionality Review *(mandatory when structural complexity is introduced)*
- **New source of truth?**: No
- **New persisted entity/table/artifact?**: No
- **New abstraction?**: Yes
- **New enum/state/reason family?**: Yes. Spec 169 introduces a first-class declaration enum for constitution-aligned surface types so inspect-rule enforcement can be driven by explicit contract data instead of inference.
- **New cross-domain UI framework/taxonomy?**: No. This feature mirrors the already-approved constitution surface taxonomy instead of inventing a new product taxonomy
- **Current operator problem**: The repository can currently verify that declarations exist, but it cannot reliably verify that the declared inspect model and action-group behavior actually match the constitution. This leaves room for regressions that look compliant on paper while drifting in rendered UI behavior.
- **Existing structure is insufficient because**: `ActionSurfaceProfile` alone is too coarse to distinguish list-first clickable-row surfaces from legitimate explicit-inspect queue and audit surfaces. The main validator also does not bring system-panel list pages into the primary discovery pass.
- **Narrowest correct implementation**: Extend the existing declaration and validator contract with one first-class `surface_type` field / enum aligned to the constitution surface taxonomy, then drive inspect-model and ordering enforcement from that field. Do not build a second registry or a broad UI meta-framework.
- **Ownership cost**: This adds a small amount of declaration metadata, stronger validator logic, and representative runtime guard tests. It also raises the review bar for future list surfaces because contributors will need to declare why a surface is clickable-row, explicit-inspect, or exempt.
- **Alternative intentionally rejected**: Another manual cleanup slice or another declaration-only rollout was rejected because the repo already completed most of that work. Documentation-only guidance without guard coverage was also rejected because it would not prevent regressions.
- **Release truth**: Current-release truth. The repo already contains both correct clickable-row patterns and correct explicit-inspect patterns, and the missing work is turning those conventions into durable enforcement.
## User Scenarios & Testing *(mandatory)*
### User Story 1 - Enforce the Correct Inspect Model (Priority: P1)
As a developer or reviewer, I need the action-surface guard to distinguish when a surface must use clickable row behavior and when it must use explicit Inspect behavior, so that new list pages cannot drift into redundant or misleading interaction models.
**Why this priority**: The constitutions highest-value list rule is “one primary inspect/open model per list.” If the repo cannot enforce that, later rollout work becomes fragile.
**Independent Test**: Can be fully tested by validating one clickable-row reference surface and one explicit-inspect reference surface, then proving the guard fails when their inspect models are swapped or duplicated.
**Acceptance Scenarios**:
1. **Given** a CRUD / List-first or Read-only Registry / Report surface that should open through row click, **When** it declares or renders a redundant lone `View` action, **Then** the guard fails with an actionable message.
2. **Given** a Queue / Review or History / Audit surface that should preserve context through explicit Inspect, **When** it declares row-click navigation as its primary inspect model without a documented exception, **Then** the guard fails.
3. **Given** a legitimate explicit-inspect surface such as Audit Log or Finding Exceptions Queue, **When** the guard evaluates its declaration and rendered behavior, **Then** it passes without being forced into a clickable-row model.
---
### User Story 2 - Enforce Stable More-Menu Ordering (Priority: P1)
As an operator, I need secondary and destructive actions to appear in a stable order across governed list surfaces, so that I can scan `More` menus without re-learning where dangerous actions are hidden.
**Why this priority**: Wave 1 normalized where actions live; the next missing layer is ensuring consistent ordering so the contract governs behavior, not just group existence.
**Independent Test**: Can be fully tested by asserting the ordered shape of representative `More` menus on existing governed CRUD resources and ensuring inspection or navigation helpers appear first, non-destructive workflow actions appear next, destructive actions sort last, and empty groups fail.
**Acceptance Scenarios**:
1. **Given** a governed `More` menu with navigation, workflow, and destructive actions, **When** the menu is validated, **Then** inspection or navigation helpers appear first, non-destructive workflow actions appear next, and destructive actions appear last.
2. **Given** a governed surface defines an `ActionGroup` or `BulkActionGroup` placeholder with no effective actions, **When** the guard runs, **Then** the guard fails.
3. **Given** a governed surface has a justified inline safe shortcut plus a `More` menu, **When** the guard evaluates it, **Then** the shortcut remains allowed while overflow actions still follow the standard helper-first, workflow-next, destructive-last ordering rules.
---
### User Story 3 - Bring System Lists Under Primary Guard Coverage (Priority: P2)
As a maintainer, I need system-panel list pages to be discovered by the same primary contract validator as tenant/admin surfaces, so that the system panel is governed by the same interaction contract instead of a parallel ad hoc check.
**Why this priority**: The repo already enrolled these system pages. The remaining risk is that the main validator still ignores them, leaving a split governance model.
**Independent Test**: Can be fully tested by proving that the primary validator discovers the enrolled system list pages and that no stale baseline exemption is required for those pages to pass.
**Acceptance Scenarios**:
1. **Given** an enrolled system-panel table page under `app/Filament/System/Pages`, **When** the primary discovery and validator pass run, **Then** the page is discovered and validated without relying on a special targeted assertion only.
2. **Given** a system auth page, widget, or other out-of-scope surface, **When** the primary discovery pass runs, **Then** it remains out of scope unless a later spec explicitly enrolls it.
3. **Given** an enrolled system page already has a declaration, **When** the primary validator runs after this feature, **Then** no new baseline exemption is needed to keep the repo green.
### Edge Cases
- A surface uses same-page selected-record inspect rather than full-page detail navigation; the contract must treat this as a legitimate explicit-inspect pattern, not as a clickable-row violation.
- A surface uses a primary linked column rather than full-row click because the row contains another dominant interaction model; the contract must allow this only when the declaration explains why row click is inappropriate.
- A run-log or audit surface intentionally has no bulk actions because the records are immutable; the validator must continue to allow this only through explicit exemption, not silent omission.
- System auth pages, dashboards, widgets, choosers, and deferred workspace-entry pages must not be accidentally swept into the new discovery scope.
- Existing deliberate exemptions for `ChooseTenant`, `ChooseWorkspace`, `ManagedTenantsLanding`, `TenantDashboard`, and the onboarding wizard must remain explicit and must not be “fixed” by broad enforcement.
- A surface may satisfy ordering rules declaratively but render contradictory runtime behavior; representative rendered-surface tests must catch this mismatch.
## Requirements *(mandatory)*
**Constitution alignment (required):** This feature introduces no Microsoft Graph calls, no domain writes, and no new long-running or scheduled work. It is a UI governance and guard-coverage feature only. Existing list, detail, queue, audit, and system pages remain the runtime surfaces; this feature only changes how their interaction contract is documented, declared, discovered, and verified.
**Constitution alignment (PROP-001 / ABSTR-001 / PERSIST-001 / STATE-001 / BLOAT-001):** This feature introduces one narrow contract extension and no new business persistence. The extension is a first-class code-level `surface_type` enum in `ActionSurfaceDeclaration`, aligned to the constitution surface taxonomy, because the current `ActionSurfaceProfile` cannot safely distinguish constitution-governed inspect models across CRUD, queue, audit, and registry surfaces. The implementation must remain the narrowest viable change to the existing contract stack and must not create a parallel registry, persistence layer, or new product-semantic framework.
**Constitution alignment (OPS-UX):** Not applicable. No `OperationRun` lifecycle, summary-counts contract, notification behavior, or service-owned transition rule changes are introduced.
**Constitution alignment (RBAC-UX):** This feature does not change any authorization policy, capability matrix, or 404 vs 403 semantics. It must preserve current tenant/admin and platform-plane authorization behavior on all representative test surfaces and must not convert UI contract checks into a security mechanism. Positive and negative authorization behavior on representative clickable-row and explicit-inspect surfaces remains part of regression coverage.
**Constitution alignment (OPS-EX-AUTH-001):** Not applicable. No authentication handshake behavior is changed.
**Constitution alignment (BADGE-001):** This feature does not introduce or change any badge vocabulary. Existing badge semantics on governed surfaces remain centralized and unchanged.
**Constitution alignment (UI-FIL-001):** This feature continues to use Filament-native table actions, `recordUrl()`, `ActionGroup`, and `BulkActionGroup` as the governing primitives. It must not introduce page-local replacement UI or local status language. Any behavior-aware runtime guard must inspect or test existing Filament action structures rather than replacing them.
**Constitution alignment (UI-NAMING-001):** This feature stabilizes interaction nouns rather than introducing new product nouns. The contract must preserve the distinction between `View` and `Inspect`, keep `More` as the standard secondary-action group label, and avoid inventing alternative labels such as `Actions` or `Open` for the same contract role unless a later naming spec explicitly changes the vocabulary.
**Constitution alignment (UI-CONST-001 / UI-SURF-001 / UI-HARD-001 / UI-EX-001 / UI-REVIEW-001):** This feature is a direct enforcement slice for the operator-surface constitution. It must codify the inspect decision tree for the existing surface types, document where row click is required, allowed, or forbidden, define where secondary and destructive actions live, and preserve catalogued exceptions for deferred surface families. The resulting validator and guard tests must fail when a declaration claims conformance but the rendered behavior violates the constitution.
**Constitution alignment (OPSURF-001):** This feature does not change the operator-first information hierarchy of covered pages, but it does enforce the interaction layer beneath that hierarchy. Queue and audit surfaces must preserve context through explicit inspect. List-first and registry surfaces must preserve one obvious open path. Dangerous actions must remain secondary and never compete with the primary inspect model.
**Constitution alignment (UI-SEM-001 / LAYER-001 / TEST-TRUTH-001):** The feature must not add a second semantic layer above the existing declaration stack. It extends the existing declaration and validator model rather than layering a new presenter-like framework on top. Tests must focus on business-visible behavior rules such as “one primary inspect model,” “explicit inspect on queue/audit,” “helper-first then workflow then destructive ordering,” and “system pages actually discovered,” not on implementation indirection for its own sake.
**Constitution alignment (Filament Action Surfaces):** This feature materially changes the Action Surface Contract itself. The contract remains satisfied because no affected surface may expose more than one primary inspect model, redundant `View` actions remain forbidden where row click is canonical, empty `ActionGroup` and `BulkActionGroup` placeholders remain forbidden, and destructive actions remain secondary. Existing documented exemptions for deferred pages remain explicit. No new exemption type is introduced.
**Constitution alignment (UX-001 — Layout & Information Architecture):** No create, edit, or detail page layout is redesigned. Existing view and list layouts remain in place. This feature changes interaction contract rules and guard coverage only.
### Functional Requirements
- **FR-169-001**: The system MUST codify a behavior-aware inspect decision tree for constitution surface types using the existing action-surface contract documentation and standards files.
- **FR-169-002**: `ActionSurfaceDeclaration` MUST carry a first-class `surface_type` field backed by a dedicated enum aligned to the constitution surface taxonomy.
- **FR-169-003**: The `surface_type` enum MUST explicitly distinguish at minimum these interaction classes for enforcement purposes: CRUD / List-first Resource, Read-only Registry / Report, Queue / Review, History / Audit, and Config-lite.
- **FR-169-004**: Standard CRUD / List-first and Read-only Registry / Report surfaces MUST default to one-click open behavior, normally via clickable row, unless a documented exception justifies a primary linked column.
- **FR-169-005**: Queue / Review and History / Audit surfaces MUST default to explicit Inspect or equivalent same-page selected-detail behavior and MUST NOT use row click as their primary inspect model unless a documented exception is approved.
- **FR-169-006**: Config-lite remains the only governed surface class where edit-as-inspect is allowed by default.
- **FR-169-007**: The validator and guard suite MUST fail when a surface that should be clickable-row renders a redundant lone `View` action or otherwise exposes more than one primary inspect model.
- **FR-169-008**: The validator and guard suite MUST allow legitimate explicit-inspect surfaces that preserve context, including Audit Log and Finding Exceptions Queue, without forcing them into clickable-row behavior.
- **FR-169-009**: The contract MUST define when `PrimaryLinkColumn` is allowed and MUST treat it as an exception path that requires a concrete reason row click is not the correct primary inspect model.
- **FR-169-010**: The contract MUST define ordering rules for `ActionGroup` and `BulkActionGroup` content: navigation or inspection helpers first, non-destructive lifecycle or workflow actions next, destructive actions last.
- **FR-169-011**: The guard suite MUST fail when governed `ActionGroup` or `BulkActionGroup` placeholders are empty.
- **FR-169-012**: The primary discovery pass MUST include in-scope system-panel list and table pages located under `app/Filament/System/Pages` rather than relying solely on targeted test assertions.
- **FR-169-013**: System auth pages, widgets, dashboards, choosers, and other intentionally deferred surface families MUST remain out of scope unless separately enrolled by a future spec.
- **FR-169-014**: The implementation MUST preserve the existing no-stale-exemption rule for already enrolled system pages, relation managers, monitoring pages, canonical detail pages, and singleton diagnostic pages.
- **FR-169-015**: The implementation MUST not add new baseline exemptions merely to satisfy the upgraded contract for already enrolled surface families.
- **FR-169-016**: The contract MUST keep `More` as the canonical secondary-action group label across governed surfaces unless a later naming spec changes it globally.
- **FR-169-017**: The implementation MUST update the primary developer-facing reference documents together so the behavior rules in documentation match the validator and the guard tests.
- **FR-169-018**: The guard suite MUST include representative rendered-surface tests proving that a declaration cannot claim conformance while the actual Filament table behavior violates the declared inspect model.
- **FR-169-019**: Representative rendered-surface coverage MUST include at least one clickable-row run-log surface, one explicit-inspect history/audit surface, one explicit-inspect queue/review surface, and one system-panel list surface discovered through the primary validator.
- **FR-169-020**: Representative rendered-surface coverage MUST include at least one governed `More` menu whose ordering proves helper-first, workflow-next, and destructive-last behavior.
- **FR-169-021**: The feature MUST not introduce any new domain capability, policy, migration, persisted artifact, or cross-request cache.
## UI Action Matrix *(mandatory when Filament is changed)*
| Surface | Location | Header Actions | Inspect Affordance (List/Table) | Row Actions (max 2 visible) | Bulk Actions (grouped) | Empty-State CTA(s) | View Header Actions | Create/Edit Save+Cancel | Audit log? | Notes / Exemptions |
|---|---|---|---|---|---|---|---|---|---|---|
| Monitoring Operations | `app/Filament/Pages/Monitoring/Operations.php` and `app/Filament/Resources/OperationRunResource.php` | Existing scope and return actions such as `Scope`, `Back`, and `Show all tenants` remain | `recordUrl()` full-row click to canonical run detail | None on the list | None by explicit exemption | Existing empty-state guidance to adjust filters remains | Existing run-detail header actions such as back, refresh, related links, and resumable actions remain | Not applicable | No new audit event | This is the clickable-row reference surface for the upgraded contract |
| Monitoring Audit Log | `app/Filament/Pages/Monitoring/AuditLog.php` | Existing scope and return actions remain | Explicit `Inspect` action with same-page selected-event detail | `Inspect` only | None by explicit exemption | Existing clear-filters guidance remains | Existing selected-event related-navigation actions remain | Not applicable | No new audit event | This is the History / Audit reference surface for explicit inspect |
| Finding Exceptions Queue | `app/Filament/Pages/Monitoring/FindingExceptionsQueue.php` | Existing scope and return actions remain | Explicit `Inspect` action with same-page selected-record detail | `Inspect` only | None by explicit exemption | Existing empty-state guidance and tenant-return navigation remain | Existing `Approve exception`, `Reject exception`, and related record navigation remain | Not applicable | Yes, existing decision audit remains unchanged | This is the Queue / Review reference surface for explicit inspect |
| Reporting and evidence registers | `app/Filament/Pages/Reviews/ReviewRegister.php` and `app/Filament/Pages/Monitoring/EvidenceOverview.php` | Existing filter-reset or scope-reset helpers remain | Existing clickable-row open to review or evidence detail remains | None on the list | None by explicit exemption | Existing page-specific clear-filters guidance remains | Existing review or evidence detail actions remain on the destination surface | Not applicable | No new audit event | Representative registry surfaces enrolled by this spec so non-audit scan-first lists are covered |
| System operations lists | `app/Filament/System/Pages/Ops/Runs.php`, `Failures.php`, `Stuck.php` | Existing system-page header actions remain | Existing clickable-row open to system run detail remains | None on the list unless already justified by the page | Existing immutable-list bulk behavior or explicit exemption remains | Existing page-specific empty-state behavior remains | Existing run-detail actions remain | Not applicable | No new audit event | Read-only registry reference surfaces using the Cross-panel Canonical Route Exception while preserving the canonical Operations noun |
| System directory lists | `app/Filament/System/Pages/Directory/Tenants.php` and `Workspaces.php` | Existing system-page header actions remain | Existing clickable-row open to system detail remains | None on the list unless already justified by the page | Existing bulk behavior or explicit exemption remains | Existing page-specific empty-state behavior remains | Existing detail-page actions remain | Not applicable | No new audit event | Read-only registry reference surfaces for cross-panel guard coverage |
| System access logs | `app/Filament/System/Pages/Security/AccessLogs.php` | Existing system-page header actions remain | Existing explicit inspect or context-preserving detail open remains | Existing inspect action only | Existing immutable-list bulk behavior or explicit exemption remains | Existing page-specific empty-state behavior remains | Existing detail actions remain | Not applicable | No new audit event | History / Audit reference surface in the platform plane |
| Representative read-only registry resources | `app/Filament/Resources/AlertDeliveryResource.php`, `app/Filament/Resources/BaselineSnapshotResource.php`, `app/Filament/Resources/EvidenceSnapshotResource.php`, `app/Filament/Resources/ReviewPackResource.php`, and `app/Filament/Resources/TenantReviewResource.php` | Existing resource header actions remain unchanged | Existing row-click open remains canonical; no redundant row-level `View` action is allowed | At most one justified inline safe shortcut on resources that already expose one; otherwise none | Existing detail-header lifecycle actions remain preferred; row-level destructive actions remain secondary only where already justified | Existing page-specific empty-state behavior remains | Existing view-header actions remain | Not applicable | No new audit event | Representative read-only registry resource family for v1.1 declaration rollout |
| Representative CRUD list-first resources (`Tenants`, `Policies`, `Baseline profiles`, `Backup schedules`, `Workspaces`) | `app/Filament/Resources/TenantResource.php`, `app/Filament/Resources/PolicyResource.php`, `app/Filament/Resources/BaselineProfileResource.php`, `app/Filament/Resources/BackupScheduleResource.php`, and `app/Filament/Resources/Workspaces/WorkspaceResource.php` | Existing scope and sync or lifecycle header actions remain | Existing row-click open remains canonical | One justified inline safe shortcut plus `More` | Existing bulk actions remain grouped under `More`; destructive actions stay under `More` or the detail header | Existing empty-state CTA behavior remains | Existing view or edit header actions remain | Not applicable | No new audit event | This is the representative CRUD family for overflow ordering and inline-budget enforcement |
### Key Entities *(include if feature involves data)*
- **ActionSurfaceDeclaration v1.1**: The existing declaration object extended with the minimum rule data needed to enforce inspect-model and ordering behavior.
- **Surface Type Enum**: A first-class enum on `ActionSurfaceDeclaration` aligned to the constitution surface taxonomy and used as the enforcement source for inspect-model rules.
- **Governed Surface Type**: The constitution-aligned interaction class used to decide whether a surface should be clickable-row, explicit-inspect, or edit-as-inspect.
- **Inspect Decision Rule**: The rule set that maps governed surface type to the allowed primary inspect model.
- **Action Ordering Rule**: The rule set that governs the order and legality of entries inside `ActionGroup` and `BulkActionGroup` on covered surfaces.
- **Primary Discovery Scope**: The set of Filament Resources, Pages, RelationManagers, and system-panel pages included in the repository-wide action-surface validation pass.
## Success Criteria *(mandatory)*
### Measurable Outcomes
- **SC-169-001**: 100% of the enrolled system-panel list pages covered by existing targeted tests are discovered by the primary validator after this feature ships.
- **SC-169-002**: Representative guard coverage exists for all four critical rule families: clickable-row enforcement, explicit-inspect enforcement, ordered overflow behavior, and out-of-scope exemption preservation.
- **SC-169-003**: A deliberately broken inspect-model or ordering implementation fails with an actionable message naming the violating class and the violated rule.
- **SC-169-004**: Existing reference surfaces continue to pass under the upgraded rules: clickable-row `OperationRunResource` / Monitoring Operations, explicit-inspect Audit Log, explicit-inspect Finding Exceptions Queue, and at least one system-panel list surface.
- **SC-169-005**: No new baseline exemption is added for already enrolled system pages or relation managers in order to make the upgraded contract pass.
- **SC-169-006**: The feature ships without introducing any new business persistence, any new capability family, or any product-facing route or workflow change.