50 lines
7.4 KiB
Markdown
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. |