TenantAtlas/specs/242-operational-controls/quickstart.md
Ahmed Darrazi dcf70b6df8
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 4m58s
chore: commit workspace changes (session: 242-operational-controls-session-1777207571)
2026-04-26 14:46:12 +02:00

50 lines
7.4 KiB
Markdown

# Quickstart — Operational Controls
## Prereqs
- Docker running
- Laravel Sail dependencies installed
- A platform user able to access `/system`
- Existing workspace, tenant, findings, restore-run, and operation-run factories available for tests
## Run locally
- Start containers: `cd apps/platform && ./vendor/bin/sail up -d`
- Run migrations for the new activation table: `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan migrate --no-interaction`
- Refresh the seeded local platform operator after the new capability is added: `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan db:seed --class=PlatformUserSeeder --no-interaction`
- Run targeted tests after implementation:
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/OperationalControls/OperationalControlCatalogTest.php tests/Unit/Support/OperationalControls/OperationalControlEvaluatorTest.php tests/Unit/Support/OperationalControls/OperationalControlScopeResolutionTest.php`
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/Spec113/AdminFindingsNoMaintenanceActionsTest.php tests/Feature/System/OpsControls/OperationalControlManagementTest.php tests/Feature/System/OpsRunbooks/OperationalControlRunbookGateTest.php`
- `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Findings/OperationalControlFindingsBackfillGateTest.php tests/Feature/Restore/OperationalControlRestoreExecutionGateTest.php tests/Feature/OperationalControls/OperationalControlAuthorizationSemanticsTest.php tests/Feature/OperationalControls/NoAdHocOperationalControlBypassTest.php`
- Full narrow suite: `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/OperationalControls/OperationalControlCatalogTest.php tests/Unit/Support/OperationalControls/OperationalControlEvaluatorTest.php tests/Unit/Support/OperationalControls/OperationalControlScopeResolutionTest.php tests/Feature/Filament/Spec113/AdminFindingsNoMaintenanceActionsTest.php tests/Feature/System/OpsControls/OperationalControlManagementTest.php tests/Feature/System/OpsRunbooks/OperationalControlRunbookGateTest.php tests/Feature/Findings/OperationalControlFindingsBackfillGateTest.php tests/Feature/Restore/OperationalControlRestoreExecutionGateTest.php tests/Feature/OperationalControls/OperationalControlAuthorizationSemanticsTest.php tests/Feature/OperationalControls/NoAdHocOperationalControlBypassTest.php`
- Format after implementation: `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
## Manual smoke after implementation
1. Sign in to `/system` as a platform operator with `platform.access_system_panel` and the new operational-controls management capability.
2. Sign in as a system user without the operational-controls management capability and verify `/system/ops/controls` returns 403 with the existing capability-denied UX rather than paused-state helper text.
3. Open `/system/ops/controls`, begin pausing `Findings lifecycle backfill` globally, verify the modal shows scope-impact preview before confirmation, then confirm and verify the control card exposes on-demand change history or an audit link for that change.
4. Open `/system/ops/runbooks`, choose the all-tenants findings-lifecycle path, and verify the runbook path shows an explicit paused-state message and does not start a run.
5. Open `/admin/t/{tenant}/findings` as an entitled tenant user and verify `Backfill findings lifecycle` is still presented truthfully for entitled users but blocked with the same control reason.
6. Invoke `tenantpilot:findings:backfill-lifecycle --tenant={tenant_id}` and verify the shared findings lifecycle service blocks the start with the same control state.
7. Pause `Restore execution` for one workspace only, then verify an entitled tenant in that workspace cannot start restore execution, no queued execution `RestoreRun` or `OperationRun` is created by the blocked start path, and a blocked-execution audit entry is recorded.
8. Verify an entitled tenant in a different workspace remains unaffected for `Restore execution`.
9. Resume both controls and confirm the normal start paths return without a deploy or env edit.
10. Verify audit entries exist for global pause/resume, workspace-targeted pause/resume, and blocked execution on the runbook, findings, and restore paths; confirm the blocked all-tenants runbook attempt is recorded as a platform-plane event with requested-scope metadata.
11. Time one pause or resume flow on `/system/ops/controls` and confirm the staged preview-plus-confirm path completes in under 1 minute.
## Notes
- Filament v5 remains on Livewire v4.0+ in this repo; the slice stays on native Filament pages/resources/actions.
- No panel provider registration changes are planned; Laravel 12 provider registration remains in `bootstrap/providers.php` if any provider change becomes necessary.
- No global-search behavior changes are involved because the slice adds no new searchable resource.
- The state-changing control actions are destructive-like and must use `->requiresConfirmation()`.
- Global pauses win over workspace-specific pauses in v1; no narrower workspace record re-enables a globally paused control.
- No new frontend asset pipeline is expected; no new `filament:assets` deploy step is needed unless implementation adds registered assets later.
## Implementation Close-out
- Guardrail result: `tests/Feature/OperationalControls/NoAdHocOperationalControlBypassTest.php` passed after narrowing the forbidden config check to the retired `tenantpilot.allow_admin_maintenance_actions` path instead of unrelated `tenantpilot` reads.
- Latest targeted validation passed: `export PATH="/bin:/usr/bin:/usr/local/bin:$PATH" && cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Unit/Support/OperationalControls/OperationalControlCatalogTest.php tests/Unit/Support/OperationalControls/OperationalControlEvaluatorTest.php tests/Unit/Support/OperationalControls/OperationalControlScopeResolutionTest.php tests/Feature/Filament/Spec113/AdminFindingsNoMaintenanceActionsTest.php tests/Feature/System/OpsControls/OperationalControlManagementTest.php tests/Feature/System/OpsRunbooks/OperationalControlRunbookGateTest.php tests/Feature/Findings/OperationalControlFindingsBackfillGateTest.php tests/Feature/Restore/OperationalControlRestoreExecutionGateTest.php tests/Feature/OperationalControls/OperationalControlAuthorizationSemanticsTest.php tests/Feature/OperationalControls/NoAdHocOperationalControlBypassTest.php` with `20 passed (253 assertions)`.
- Shared-helper note: `OperationalControlDecision` now exposes workspace-aware presentation helpers, the findings path routes through `FindingsLifecycleBackfillRunbookService::start()`, and restore execution is blocked before any queued execution `OperationRun`, queued execution `RestoreRun`, queue dispatch, or provider call.
- Manual smoke status: passed in the integrated browser on `http://localhost/system/ops/controls` after seeding the local platform operator and running the pending operational-controls migration; the staged global pause and resume flow for `Findings lifecycle backfill` completed successfully within the SC-001 budget.