TenantAtlas/specs/114-system-console-control-tower/tasks.md
ahmido 0cf612826f feat(114): system console control tower (merged) (#139)
Feature branch PR for Spec 114.

This branch contains the merged agent session work (see merge commit on branch).

Tests
- `vendor/bin/sail artisan test --compact tests/Feature/System/Spec114/`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #139
2026-02-28 00:15:31 +00:00

202 lines
15 KiB
Markdown

---
description: "Executable task breakdown for Spec 114 implementation"
---
# Tasks: System Console Control Tower (Spec 114)
**Input**: Design documents from `specs/114-system-console-control-tower/`
**Docs used**:
- `specs/114-system-console-control-tower/spec.md`
- `specs/114-system-console-control-tower/plan.md`
- `specs/114-system-console-control-tower/research.md`
- `specs/114-system-console-control-tower/data-model.md`
- `specs/114-system-console-control-tower/contracts/system-console-control-tower.openapi.yaml`
- `specs/114-system-console-control-tower/quickstart.md`
**Tests**: REQUIRED (Pest) for runtime behavior changes.
---
## Phase 1: Setup (Shared Structure)
- [X] T001 Review existing System panel primitives in `app/Providers/Filament/SystemPanelProvider.php`, System auth/security primitives in `app/Filament/System/Pages/Auth/Login.php` + `app/Services/Auth/BreakGlassSession.php`, and System tests in `tests/Feature/System/Spec113/` + `tests/Feature/Auth/BreakGlassModeTest.php` + `tests/Feature/System/OpsRunbooks/` (confirm session isolation cookie middleware, login throttling + audit trail, break-glass banner/audits, 404/403 semantics, and existing Ops-UX start-surface contract patterns)
- [X] T002 [P] Create new System page namespaces for Spec 114 in `app/Filament/System/Pages/Directory/` and `app/Filament/System/Pages/Security/`
- [X] T003 [P] Create new System Blade view directories for Spec 114 in `resources/views/filament/system/pages/directory/` and `resources/views/filament/system/pages/security/`
---
## Phase 2: Foundational (Blocking Prerequisites)
- [X] T004 Extend platform capability registry with Spec 114 constants in `app/Support/Auth/PlatformCapabilities.php` (add `platform.console.view`, `platform.directory.view`, `platform.operations.view`, `platform.operations.manage`; keep existing constants for compatibility)
- [X] T005 Update seeded platform operator capabilities in `database/seeders/PlatformUserSeeder.php` to include the new Spec 114 capabilities
- [X] T006 Add stuck threshold defaults to `config/tenantpilot.php` under `system_console.stuck_thresholds.{queued_minutes,running_minutes}` (used by `/system/ops/stuck`)
- [X] T007 [P] Implement a typed time-window helper in `app/Support/SystemConsole/SystemConsoleWindow.php` (allowed: `1h`, `24h` default, `7d`; provides start timestamp)
- [X] T008 [P] Implement stuck run classification helper in `app/Support/SystemConsole/StuckRunClassifier.php` (DB-only query constraints for queued/running + thresholds)
- [X] T009 Update System panel access regression tests in `tests/Feature/System/Spec113/AuthorizationSemanticsTest.php` (if needed) to preserve the clarified rule: wrong guard / unauthenticated → 404; platform user missing page capability → 403
- [X] T010 Add Spec 114 access semantics tests in `tests/Feature/System/Spec114/SystemConsoleAccessSemanticsTest.php` (assert 404 for tenant-guard requests across representative `/system/*` URLs and 403 for platform users missing required capabilities; also assert `/system` uses a distinct session cookie name from `/admin` to enforce SR-006)
**Checkpoint**: Capabilities/config/helpers/tests exist; user story work can begin.
---
## Phase 3: User Story 1 — Global Health & Triage Entry (Priority: P1) 🎯 MVP
**Goal**: Control Tower KPIs + top offenders + quick clickthrough to a canonical run detail.
**Independent Test**: A platform user can open `/system` (dashboard), switch time window, see KPIs/top offenders, and open a run detail.
### Tests (write first)
- [X] T011 [P] [US1] Add Control Tower access + window default tests in `tests/Feature/System/Spec114/ControlTowerDashboardTest.php`
- [X] T012 [P] [US1] Add canonical run detail access + data-minimization tests in `tests/Feature/System/Spec114/CanonicalRunDetailTest.php` (assert SR-004 v1 behavior: no raw error/context drilldowns; only sanitized summaries render)
### Implementation
- [X] T013 [US1] Gate the dashboard with `platform.console.view` and add a time-window switcher to header actions in `app/Filament/System/Pages/Dashboard.php`
- [X] T014 [P] [US1] Create KPIs widget in `app/Filament/System/Widgets/ControlTowerKpis.php` (DB-only aggregation on `operation_runs` within selected window)
- [X] T015 [P] [US1] Create “Top offenders” widget in `app/Filament/System/Widgets/ControlTowerTopOffenders.php` (group failed runs by tenant/workspace/type within window)
- [X] T016 [P] [US1] Create “Recently failed operations” widget in `app/Filament/System/Widgets/ControlTowerRecentFailures.php` (links to canonical run detail via `app/Support/System/SystemOperationRunLinks.php`)
- [X] T017 [US1] Register Spec 114 widgets on the System dashboard in `app/Filament/System/Pages/Dashboard.php` (ensure all widget queries are DB-only)
- [X] T018 [US1] Convert the System runs list to *global* runs (not runbook-only) in `app/Filament/System/Pages/Ops/Runs.php` and keep the table rendering in `resources/views/filament/system/pages/ops/runs.blade.php`
- [X] T019 [US1] Make run detail canonical (remove runbook-only + platform-workspace-only constraints) and gate it with `platform.operations.view` in `app/Filament/System/Pages/Ops/ViewRun.php`
- [X] T020 [US1] Generalize the run detail rendering to non-runbook runs in `resources/views/filament/system/pages/ops/view-run.blade.php` (keep sanitized failures + avoid leaking sensitive context by default)
**Checkpoint**: US1 is shippable and independently testable.
---
## Phase 4: User Story 2 — Directory for Workspaces & Tenants (Priority: P2)
**Goal**: Provide cross-workspace directory pages with health signals and safe links into ops views.
**Independent Test**: A platform user can list workspaces/tenants, open details, and jump to filtered run listings without session bridging.
### Tests (write first)
- [X] T021 [P] [US2] Add workspaces directory access + listing tests in `tests/Feature/System/Spec114/DirectoryWorkspacesTest.php`
- [X] T022 [P] [US2] Add tenants directory access + listing tests in `tests/Feature/System/Spec114/DirectoryTenantsTest.php`
### Implementation
- [X] T023 [US2] Add a System health badge domain (OK/Warn/Critical/Unknown) in `app/Support/Badges/BadgeDomain.php`, map it in `app/Support/Badges/BadgeCatalog.php`, and implement its mapper in `app/Support/Badges/Domains/SystemHealthBadge.php`
- [X] T024 [P] [US2] Add badge mapping semantics tests in `tests/Feature/Badges/SystemHealthBadgeSemanticsTest.php`
- [X] T025 [P] [US2] Add directory URL helpers in `app/Support/System/SystemDirectoryLinks.php` (workspaces/tenants index + detail URLs, plus safe “Open in /admin” URL-only links)
- [X] T026 [US2] Implement Workspaces index page (table + filters) in `app/Filament/System/Pages/Directory/Workspaces.php` with view `resources/views/filament/system/pages/directory/workspaces.blade.php` (gate with `platform.directory.view`)
- [X] T027 [US2] Implement Workspace detail page in `app/Filament/System/Pages/Directory/ViewWorkspace.php` with view `resources/views/filament/system/pages/directory/view-workspace.blade.php` (tenants summary + recent ops links)
- [X] T028 [US2] Implement Tenants index page in `app/Filament/System/Pages/Directory/Tenants.php` with view `resources/views/filament/system/pages/directory/tenants.blade.php`
- [X] T029 [US2] Implement Tenant detail page in `app/Filament/System/Pages/Directory/ViewTenant.php` with view `resources/views/filament/system/pages/directory/view-tenant.blade.php` (connectivity/permission signals + recent ops)
- [X] T030 [US2] Ensure any “Open in /admin” links remain URL-only (no auto-login, no session bridging) in `resources/views/filament/system/pages/directory/view-workspace.blade.php` and `resources/views/filament/system/pages/directory/view-tenant.blade.php`
**Checkpoint**: Directory is usable and independently testable.
---
## Phase 5: User Story 3 — Operations Triage Actions & Auditability (Priority: P3)
**Goal**: Provide failures/stuck/access-log surfaces plus safe triage actions with confirmation and audit trails.
**Independent Test**: A view-only platform user can inspect but cannot mutate; a manage-capable user can perform a supported triage action and an audit log entry is written.
### Tests (write first)
- [X] T031 [P] [US3] Add failures view access + prefilter tests in `tests/Feature/System/Spec114/OpsFailuresViewTest.php`
- [X] T032 [P] [US3] Add stuck view access + stuck classification boundary tests in `tests/Feature/System/Spec114/OpsStuckViewTest.php`
- [X] T033 [P] [US3] Add access logs filtering tests in `tests/Feature/System/Spec114/AccessLogsTest.php` (assert `platform.auth.login` includes both success + failure events and includes `platform.break_glass.*` actions)
- [X] T034 [P] [US3] Add triage action authorization + audit-write tests in `tests/Feature/System/Spec114/OpsTriageActionsTest.php` (include an Ops-UX contract regression assertion for any triage action that queues work: intent-only toast + working “View run” link + no queued database notifications, mirroring `tests/Feature/System/OpsRunbooks/`)
### Implementation
- [X] T035 [US3] Implement failures page in `app/Filament/System/Pages/Ops/Failures.php` and view `resources/views/filament/system/pages/ops/failures.blade.php` (prefilter failed runs; gate with `platform.operations.view`)
- [X] T036 [US3] Implement stuck page in `app/Filament/System/Pages/Ops/Stuck.php` and view `resources/views/filament/system/pages/ops/stuck.blade.php` (use `app/Support/SystemConsole/StuckRunClassifier.php`; gate with `platform.operations.view`)
- [X] T037 [US3] Implement access logs page in `app/Filament/System/Pages/Security/AccessLogs.php` and view `resources/views/filament/system/pages/security/access-logs.blade.php` (AuditLog list scoped to `platform.auth.login` + `platform.break_glass.*`; gate with `platform.console.view`)
- [X] T038 [US3] Implement triage policy + execution in `app/Services/SystemConsole/OperationRunTriageService.php` (define retryable/cancelable allowlist by operation type; “mark investigated” requires reason and writes audit)
- [X] T039 [US3] Implement system-console audit logging helper in `app/Services/SystemConsole/SystemConsoleAuditLogger.php` (wrap `app/Services/Intune/AuditLogger.php` using the `platform` tenant; stable action IDs; includes break-glass marker)
- [X] T040 [US3] Add manage-only Filament actions (Retry/Cancel/Mark investigated) to run tables and run detail in `app/Filament/System/Pages/Ops/Runs.php`, `app/Filament/System/Pages/Ops/Failures.php`, `app/Filament/System/Pages/Ops/Stuck.php`, and `app/Filament/System/Pages/Ops/ViewRun.php` (all mutations use `->action(...)` + `->requiresConfirmation()`, “Mark investigated” includes a required reason field)
**Checkpoint**: All Spec 114 operator actions are capability-gated, confirmed, and audited.
---
## Phase 6: Polish & Cross-Cutting Concerns
- [X] T041 [P] Run code formatting on touched files via `vendor/bin/sail` (use `vendor/bin/sail bin pint --dirty --format agent`)
- [X] T042 Run Spec 114 focused tests via `vendor/bin/sail` in `tests/Feature/System/Spec114/`
- [X] T043 Validate quickstart steps remain accurate in `specs/114-system-console-control-tower/quickstart.md` (adjust if needed)
- [X] T044 [P] Optional performance follow-up: add indexes for windowed queries in `database/migrations/` (only if needed after measuring/explain plans; deferred for now because current EXPLAIN baselines do not indicate index pressure at present data volumes)
- [X] T045 [P] Performance validation: capture a baseline for the primary list pages (dashboard widgets, `/system/ops/runs`, `/system/ops/failures`, `/system/ops/stuck`, directory lists) and only then decide whether T044 is needed
- [X] T046 Confirm Runbook navigation/shortcuts satisfy FR-007: System navigation provides Runbooks entry, and the canonical run detail exposes a “Go to runbooks” affordance (or explicitly documents “coming soon” where applicable)
- [X] T047 Explicitly document v1 scope decisions in tasks acceptance notes: Export (FR-009) is deferred; raw error/context drilldowns (SR-004) are not present in v1
---
## Phase 7: Enterprise UI Polish
**Goal**: Elevate the System Console from functional to enterprise-grade: richer page content, contextual badges in navigation, visual hierarchy for break-glass actions, and visible audit trails.
- [X] T048 [P] [Polish] Add stats overview widget to Recovery > Repair Workspace Owners page (`app/Filament/System/Pages/Ops/RepairWorkspaceOwners.php`): show "X healthy | Y ownerless | Z stuck" counts above the purpose box
- [X] T049 [P] [Polish] Add a Workspaces table to Repair Workspace Owners page listing workspaces with owner status (name, owner count, last activity, health badge) — currently the page is empty below the purpose box
- [X] T050 [Polish] Restyle the "Assign owner (break-glass)" button: use `->icon('heroicon-o-shield-exclamation')` + `->color('danger')` with better label "Emergency: Assign Owner" to distinguish intentional danger-action from error-state appearance
- [X] T051 [P] [Polish] Add navigation badge counts to Ops sidebar items (Failures, Stuck) showing live counts (e.g. "3" next to Failures, "1" next to Stuck) using `::getNavigationBadge()` + `::getNavigationBadgeColor()`
- [X] T052 [P] [Polish] Add navigation badge to Recovery > Repair Workspace Owners showing count of ownerless workspaces
- [X] T053 [Polish] Add "Recent break-glass actions" infolist/table to the Repair Workspace Owners page showing the last 10 audit log entries for `platform.break_glass.*` actions (who, when, what workspace)
- [X] T054 [P] [Polish] Add a System Console health summary widget to the Dashboard (`app/Filament/System/Pages/Dashboard.php`) showing traffic-light indicator (green/yellow/red) based on failure + stuck counts
- [X] T055 Run Pint on touched files via `vendor/bin/sail bin pint --dirty --format agent`
- [X] T056 Run Spec 114 focused tests via `vendor/bin/sail artisan test --compact tests/Feature/System/Spec114/`
---
## Dependencies & Execution Order
```mermaid
graph TD
P1[Phase 1: Setup] --> P2[Phase 2: Foundational]
P2 --> US1[Phase 3: US1 (MVP)]
P2 --> US2[Phase 4: US2]
P2 --> US3[Phase 5: US3]
US1 --> POL[Phase 6: Polish]
US2 --> POL
US3 --> POL
POL --> ENT[Phase 7: Enterprise UI Polish]
```
- Phase 2 blocks all user stories.
- US2 and US3 can proceed in parallel after Phase 2, but MVP should ship US1 first.
---
## Parallel Execution Examples
### User Story 1
- Parallel: T011 + T012 (tests)
- Parallel: T014 + T015 + T016 (widgets)
### User Story 2
- Parallel: T021 + T022 (tests)
- Parallel: T024 + T025 (badge semantics)
### User Story 3
- Parallel: T031 + T032 + T033 + T034 (tests)
- Parallel: T035 + T036 + T037 (page scaffolds)
---
## Implementation Strategy
### MVP First (US1 only)
1) Complete Phase 1 + Phase 2
2) Ship US1 (dashboard widgets + global runs + canonical run detail)
3) Add US2 directory
4) Add US3 triage pages/actions + access logs
---
## Acceptance Notes (v1 Scope)
- FR-009 Export is explicitly deferred for v1.
- SR-004 raw error/context drilldowns are intentionally not exposed in v1 run detail views.