TenantAtlas/specs/170-system-operations-surface-alignment/plan.md
ahmido fdd3a85b64 feat: align system operations surfaces (#201)
## Summary
- align the system-panel Operations, Failed operations, and Stuck operations pages to the read-only registry contract by removing inline row triage and keeping row-click inspection
- keep retry, cancel, and mark-investigated behavior on the canonical system operation detail page while adding the explicit `Show all operations` return path and updated `Operations / Operation` copy
- add and update focused Pest and Livewire coverage for list CTA behavior, detail-owned triage, and view-only versus manage-capable platform access
- add Spec 170 implementation artifacts plus the follow-on Spec 171 and Spec 172 packages

## Testing
- `vendor/bin/sail artisan test --compact tests/Feature/System/Spec114/OpsTriageActionsTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/Guards/ActionSurfaceContractTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/System/Spec114/OpsFailuresViewTest.php`
- `vendor/bin/sail artisan test --compact tests/Feature/System/Spec114/OpsStuckViewTest.php`
- integrated browser smoke on `/system/ops/runs`, `/system/ops/failures`, `/system/ops/stuck`, empty states via search filter, and detail-page retry confirmation visibility

## Notes
- branch pushed from `170-system-operations-surface-alignment`
- latest commit: `64b4d741 feat: align system operations surfaces`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #201
2026-03-30 19:08:56 +00:00

9.3 KiB

Implementation Plan: System Operations Surface Alignment

Branch: 170-system-operations-surface-alignment | Date: 2026-03-30 | Spec: /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/170-system-operations-surface-alignment/spec.md Input: Feature specification from /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/170-system-operations-surface-alignment/spec.md

Summary

Align the system-panel Operations, Failed operations, and Stuck operations pages to their declared ReadOnlyRegistryReport surface semantics by removing inline triage from the list rows, preserving full-row navigation to the canonical system operation detail page, standardizing visible naming to Operations / Operation, and adding the required list CTA and detail return-path behavior while keeping retry/cancel/mark-investigated ownership on the existing ViewRun page. The implementation stays narrow: no schema, new capability, or service-model changes; only Filament page behavior, visible operator copy, and the associated Pest/Livewire guard coverage are updated.

Technical Context

Language/Version: PHP 8.4, Laravel 12, Livewire v4, Filament v5
Primary Dependencies: laravel/framework, filament/filament, livewire/livewire, pestphp/pest
Storage: PostgreSQL with existing operation_runs and audit_logs tables; no schema changes
Testing: Pest feature tests with Livewire component assertions, executed through Laravel Sail
Target Platform: Laravel web application running in Sail locally and containerized Linux environments in staging/production
Project Type: Laravel monolith with Filament panels
Performance Goals: Preserve current DB-only list rendering, eager loading of tenant and workspace, and existing pagination/sort behavior with no extra remote calls
Constraints: Platform plane only; no new pages/capabilities/persistence; visible naming must align to Operations / Operation; destructive triage stays confirmation-gated; existing queued-toast and audit behavior must remain intact
Scale/Scope: Four existing system-panel pages, one existing detail Blade view, one existing triage service, and the focused feature/guard tests that encode current row-action behavior

Constitution Check

GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.

  • PASS Inventory-first / snapshots-second: the feature does not change inventory, backups, or snapshot truth.
  • PASS Read/write separation: no new writes are introduced; existing retry/cancel/mark-investigated flows remain explicit operator actions with confirmation where required.
  • PASS Graph contract path: no Microsoft Graph call path is touched.
  • PASS Deterministic capabilities: existing PlatformCapabilities::OPERATIONS_VIEW and PlatformCapabilities::OPERATIONS_MANAGE remain the canonical gates.
  • PASS RBAC-UX plane separation: the slice is limited to /system surfaces and existing platform guard semantics.
  • PASS Destructive confirmation standard: cancel remains ->requiresConfirmation() on the detail header.
  • PASS Ops-UX 3-surface feedback: retry continues to use OperationUxPresenter::queuedToast(...); cancel and mark-investigated remain local terminal confirmations without adding queued/running notifications.
  • PASS Ops lifecycle ownership: status/outcome mutation continues to flow through OperationRunService inside OperationRunTriageService; no new lifecycle path is introduced.
  • PASS Proportionality / bloat: the feature removes duplicated interaction semantics and adds no new persistence, abstraction, state family, or taxonomy.
  • PASS Badge semantics: list/detail badge rendering stays on the shared badge catalog and renderer.
  • PASS Filament-native UI: the change stays inside existing Filament pages, row navigation, header actions, and confirmations.
  • PASS UI surface taxonomy: Runs, Failures, and Stuck remain ReadOnlyRegistryReport; ViewRun remains the detail-first operational surface.
  • PASS UI inspect model: each list will expose exactly one primary inspect model, recordUrl() row click.
  • PASS UI action hierarchy: registry lists will have no inline triage; detail header remains the single triage owner.
  • PASS UI naming scope: the changed system surfaces standardize visible copy to Operations / Operation while keeping internal route stability explicit.
  • PASS Empty-state CTA rule: each changed list surface will define exactly one page-appropriate CTA and matching header action.
  • PASS Placeholder/empty-group ban: no empty groups are introduced; bulk actions remain absent because there is no real bulk use case.
  • PASS OPSURF page contract: the governing spec already defines persona, operator question, default truth, mutation scope, and dangerous actions.
  • PASS Testing truth: implementation will update behavior guards, not just declarations.

Project Structure

Documentation (this feature)

specs/170-system-operations-surface-alignment/
├── plan.md
├── research.md
├── data-model.md
├── quickstart.md
├── contracts/
│   └── system-ops-surface-contract.yaml
└── tasks.md

Source Code (repository root)

app/
├── Filament/
│   └── System/
│       └── Pages/
│           └── Ops/
│               ├── Runs.php
│               ├── Failures.php
│               ├── Stuck.php
│               └── ViewRun.php
├── Services/
│   └── SystemConsole/
│       └── OperationRunTriageService.php
├── resources/
│   └── views/
│       └── filament/
│           └── system/
│               └── pages/
│                   └── ops/
│                       └── view-run.blade.php
└── Support/
    └── System/
        └── SystemOperationRunLinks.php

tests/
└── Feature/
    ├── Guards/
    │   └── ActionSurfaceContractTest.php
    └── System/
        └── Spec114/
            ├── OpsTriageActionsTest.php
            ├── OpsFailuresViewTest.php
            └── OpsStuckViewTest.php

Structure Decision: This is a single Laravel application. The implementation is confined to existing system-panel Filament pages and existing Pest feature/guard tests. No new application layer or directory is needed.

Complexity Tracking

No constitution waiver is expected. This slice reduces surface complexity instead of introducing a new layer.

Violation Why Needed Simpler Alternative Rejected Because
None Not applicable Not applicable

Proportionality Review

  • Current operator problem: the three system list pages are declared as read-only registry surfaces but still expose direct triage actions, leave empty-state navigation underdefined, and continue to present Runs as a competing visible noun beside the canonical Operations vocabulary.
  • Existing structure is insufficient because: the current hybrid model forces operators to choose between acting in-row and opening the richer detail page, while the constitution requires one primary inspect model, stable nouns, and explicit CTA behavior for changed list surfaces.
  • Narrowest correct implementation: remove list row triage actions, keep recordUrl() row-click navigation, standardize visible copy to Operations / Operation, add one clear list CTA per changed surface, add a Show all operations return path on the detail page, and update the existing tests to assert the aligned behavior.
  • Ownership cost created: low. The change requires focused updates to Filament page classes and the behavior guards that currently encode list-level triage.
  • Alternative intentionally rejected: reclassifying the list pages as queue/review surfaces or adding new exception types was rejected because these pages are scan-first registries, not context-preserving decision queues.
  • Release truth: current-release truth. The canonical detail page and triage service already exist today; the feature removes duplication rather than preparing speculative future structure.

Post-Design Constitution Re-check

  • PASS UI-CONST-001 / UI-SURF-001: the artifacts keep list pages in the registry class and the detail page as the triage owner.
  • PASS UI-HARD-001: the target design leaves each system list with exactly one primary inspect model and zero inline destructive actions.
  • PASS UI-EX-001: no new exception type or exemption is needed for this slice.
  • PASS OPSURF-001: list pages stay scan-first, while the detail page remains the context-rich operational surface.
  • PASS RBAC-UX-001 to RBAC-UX-005: view/manage separation, server-side enforcement, and destructive confirmation rules remain unchanged.
  • PASS UI-NAMING-001: visible system-surface nomenclature now aligns to Operations / Operation.
  • PASS Empty-state CTA requirement: the design now defines a primary CTA for each changed list surface and a return path on the detail page.
  • PASS BLOAT-001: no new persistence, abstraction, state family, or taxonomy was introduced during design.
  • PASS Filament v5 / Livewire v4 guardrails: the plan keeps changes inside existing Filament pages and does not require provider or asset registration changes.