- Replace view-only row buttons with clickable rows (recordUrl)\n- Update action-surface contract slot to InspectAffordance + validator support\n- Add golden guard tests + contract doc\n- Update SpecKit constitution/templates to include inspection affordance rule
4.6 KiB
Implementation Plan: Action Surface Contract + CI Enforcement
Branch: 082-action-surface-contract | Date: 2026-02-08 | Spec: specs/082-action-surface-contract/spec.md
Input: Feature specification from specs/082-action-surface-contract/spec.md
Summary
Introduce a declarative “Action Surface Declaration” for every in-scope admin UI component (Resources, Pages, embedded relationship sub-lists), enforce it via a deterministic Pest guard in CI, and add representative runtime tests for constitution-critical action behavior.
Key behavior:
- Contract profiles define minimum required action slots (list header/row/bulk/empty-state, detail header).
- Declarations must satisfy each required slot or explicitly exempt it with a reason.
- CI fails on missing declarations, missing required slots, or empty exemption reasons.
- Representative runtime tests verify grouping/confirmation/RBAC/canonical-run-link behavior on selected surfaces.
Technical Context
Language/Version: PHP 8.4.x
Primary Dependencies: Laravel 12, Filament v5, Livewire v4
Storage: PostgreSQL (Sail)
Testing: Pest v4 (PHPUnit 12 runner)
Target Platform: Web application (Laravel Sail for local; Dokploy for deploy)
Project Type: Laravel monolith (admin console via Filament panels)
Performance Goals: Contract validation completes in < 1s locally/CI (pure PHP, no network)
Constraints:
- Deterministic CI enforcement (no Livewire browser interactions)
- No new external calls introduced
- Must preserve RBAC semantics (non-member 404; member missing capability 403)
- Must not change panel architecture (tenant/admin/system panels remain)
- No deep runtime introspection of every Filament action in CI for this iteration Scale/Scope: ~100 Filament classes (Resources/Pages/RelationManagers); enforcement is repo-wide within scope
Constitution Check
GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.
- Inventory-first: N/A (this feature is UI governance; no inventory model changes)
- Read/write separation: N/A (no new domain writes introduced by the validator)
- Graph contract path: PASS (no new Graph calls)
- Deterministic capabilities: PASS (capability rules stay registry-driven)
- RBAC-UX: PASS (enforcement continues to use central UI helpers; server-side remains authoritative)
- Run observability: PASS (validator runs in CI only; no operations started)
- Data minimization: PASS (no new storage)
- Badge semantics (BADGE-001): N/A
- Filament UI Action Surface Contract: PASS (this feature implements the CI gate itself)
Plan Phases
Phase 0 — Research (output: research.md)
Decide and document:
- How to enumerate in-scope classes for tenant + admin panels (excluding widgets)
- How declarations are attached (static method vs attributes vs config)
- What “slots” exist and how exemptions are represented (reason required; tracking optional)
- How the Pest guard reports actionable failures
Phase 1 — Design (outputs: data-model.md, contracts/*, quickstart.md)
Design artifacts:
- Data model for declarations, slots, exemptions, and profiles
- JSON schema contract for the declaration payload (for future tooling)
- Quickstart explaining how to add a declaration + how to run the guard
Phase 2 — Planning (output: tasks.md later via /speckit.tasks)
Implementation plan will include:
- New support classes under
app/Support/Ui/ActionSurface/** - Pest guard test under
tests/Feature/Guards/** - Minimal retrofit for existing “bulk none” surfaces via declarations + targeted exemptions (repo-green first)
- Representative runtime assertions for action grouping, confirmation, and canonical run links
Project Structure
Documentation (this feature)
specs/082-action-surface-contract/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
└── tasks.md
Source Code (repository root)
app/
├── Filament/
│ ├── Resources/
│ ├── Pages/
│ └── System/ # out-of-scope for this feature’s validator
├── Providers/Filament/ # panel providers (tenant/admin/system)
└── Support/
├── Rbac/ # UiEnforcement + WorkspaceUiEnforcement (existing)
└── Ui/ActionSurface/ # NEW: profiles, slots, declarations, validator
tests/
└── Feature/
└── Guards/ # NEW: Action surface contract CI gate
Structure Decision: Laravel monolith. Action-surface enforcement ships as support-domain classes + a Pest guard.
Complexity Tracking
No constitution violations required.