TenantAtlas/specs/194-governance-friction-hardening/tasks.md
ahmido acc8947384 feat: harden governance action semantics (#229)
## Summary
- add the Spec 194 governance action catalog, friction classes, reason policies, and regression guards
- align exception, review, evidence, finding, tenant, provider connection, and system run actions to the shared semantics model
- add focused feature, RBAC, audit, unit, and browser coverage, including the tenant detail triage header consistency update

## Verification
- ran the focused Spec 194 verification pack from the quickstart and task plan
- ran targeted tenant triage coverage after the detail-header update
- ran `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`

## Filament Notes
- Filament v5 / Livewire v4 compliance preserved
- provider registration remains in `apps/platform/bootstrap/providers.php`
- globally searchable resources were not changed
- destructive actions remain confirmation-gated and server-authorized
- no new Filament assets were introduced; the existing `cd apps/platform && php artisan filament:assets` deploy step stays unchanged

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #229
2026-04-12 21:21:44 +00:00

18 KiB

Tasks: Governance Friction Hardening and Operator Vocabulary

Input: Design documents from /specs/194-governance-friction-hardening/
Prerequisites: plan.md, spec.md, research.md, data-model.md, contracts/governance-action-semantics.logical.openapi.yaml, quickstart.md

Tests: Required. This feature changes runtime behavior on existing Filament v5 / Livewire v4 operator surfaces, so Pest unit, feature, RBAC, audit, and browser smoke coverage must be added or extended.

Organization: Tasks are grouped by user story so each slice stays independently testable. Recommended delivery order is US1 -> US2 -> US3 -> US4, with US1 as the MVP cut after the shared catalog and guard foundation is in place.

Phase 1: Setup (Shared Infrastructure)

Purpose: Create the dedicated support and test entry points for Spec 194 without changing runtime behavior yet.

  • T001 Create the governance action support scaffolds in apps/platform/app/Support/Ui/GovernanceActions/GovernanceActionCatalog.php, apps/platform/app/Support/Ui/GovernanceActions/GovernanceActionRule.php, apps/platform/app/Support/Ui/GovernanceActions/Enums/GovernanceFrictionClass.php, and apps/platform/app/Support/Ui/GovernanceActions/Enums/GovernanceReasonPolicy.php
  • T002 [P] Create the Spec 194 unit and guard test scaffolds in apps/platform/tests/Unit/Ui/GovernanceActions/GovernanceActionCatalogTest.php and apps/platform/tests/Feature/Guards/Spec194GovernanceActionSemanticsGuardTest.php
  • T003 [P] Create the browser smoke scaffold in apps/platform/tests/Browser/Spec194GovernanceFrictionSmokeTest.php

Checkpoint: The new support namespace and dedicated Spec 194 test entry points exist, so shared rule work can begin without mixing this slice into unrelated suites.


Phase 2: Foundational (Blocking Prerequisites)

Purpose: Codify the shared governance semantics inventory and regression gate that every story depends on.

⚠️ CRITICAL: No user story work should start before this phase is complete.

  • T004 [P] Add catalog invariant, deterministic F1 reason-policy, and documented-deviation coverage in apps/platform/tests/Unit/Ui/GovernanceActions/GovernanceActionCatalogTest.php
  • T005 [P] Add family, surface, vocabulary, indirect risk-acceptance continuity, and exception regression coverage in apps/platform/tests/Feature/Guards/Spec194GovernanceActionSemanticsGuardTest.php
  • T006 [P] Implement the friction and reason enums in apps/platform/app/Support/Ui/GovernanceActions/Enums/GovernanceFrictionClass.php and apps/platform/app/Support/Ui/GovernanceActions/Enums/GovernanceReasonPolicy.php
  • T007 [P] Implement the shared rule value object in apps/platform/app/Support/Ui/GovernanceActions/GovernanceActionRule.php
  • T008 Implement the canonical family inventory, surface bindings, deterministic F1 reason defaults, indirect risk-acceptance continuity, and documented deviations in apps/platform/app/Support/Ui/GovernanceActions/GovernanceActionCatalog.php

Checkpoint: The repo can enumerate in-scope governance actions, classify them, and fail CI on undocumented semantic drift before any page-level refactor starts.


Phase 3: User Story 1 - Make a Formal Exception Decision Safely (Priority: P1) 🎯 MVP

Goal: Make queue and detail exception decisions use one predictable friction, reason, and vocabulary contract.

Independent Test: Open the finding exceptions queue and one finding exception detail page, then confirm approve, reject, renew, and revoke follow the shared exception-family semantics without changing any review, evidence, run, or tenant lifecycle pages.

Tests for User Story 1

Note

: Write these tests first and confirm they fail before implementation.

  • T009 [P] [US1] Extend queue selection-state, modal friction, and reason-prompt coverage in apps/platform/tests/Feature/Monitoring/FindingExceptionsQueueHierarchyTest.php and apps/platform/tests/Feature/Monitoring/FindingExceptionsQueueTest.php
  • T010 [P] [US1] Extend exception lifecycle, authorization, header-discipline, audit, and indirect risk-acceptance vocabulary continuity coverage in apps/platform/tests/Feature/Findings/FindingExceptionWorkflowTest.php, apps/platform/tests/Feature/Findings/FindingExceptionRenewalTest.php, apps/platform/tests/Feature/Findings/FindingExceptionRevocationTest.php, apps/platform/tests/Feature/Findings/FindingExceptionAuthorizationTest.php, apps/platform/tests/Feature/Findings/FindingExceptionPolicyTest.php, and apps/platform/tests/Feature/Filament/FindingExceptionHeaderDisciplineTest.php

Implementation for User Story 1

  • T011 [US1] Align exception-family reason propagation, canonical audit verbs, and success copy in apps/platform/app/Services/Findings/FindingExceptionService.php
  • T012 [US1] Refactor queue decision actions to consume catalog rules in apps/platform/app/Filament/Pages/Monitoring/FindingExceptionsQueue.php
  • T013 [US1] Refactor exception detail lifecycle actions to consume catalog rules and keep revoke as the separated F3 action in apps/platform/app/Filament/Resources/FindingExceptionResource/Pages/ViewFindingException.php

Checkpoint: Exception governance is independently functional and consistent across queue and detail surfaces.


Phase 4: User Story 2 - Distinguish Governance Lifecycle from Technical Refresh (Priority: P1)

Goal: Make review publication or archival and evidence refresh or expiry read as clearly different action families instead of peer mutations.

Independent Test: Open a tenant review detail page and an evidence snapshot detail page, then confirm publish and archive are distinct from export, while refresh remains lighter than expire, without changing run or tenant lifecycle surfaces.

Tests for User Story 2

Note

: Write these tests first and confirm they fail before implementation.

  • T014 [P] [US2] Extend review lifecycle, export separation, authorization, and audit coverage in apps/platform/tests/Feature/TenantReview/TenantReviewUiContractTest.php, apps/platform/tests/Feature/TenantReview/TenantReviewLifecycleTest.php, apps/platform/tests/Feature/TenantReview/TenantReviewRbacTest.php, apps/platform/tests/Feature/TenantReview/TenantReviewAuditLogTest.php, apps/platform/tests/Feature/TenantReview/TenantReviewExecutivePackTest.php, and apps/platform/tests/Feature/Filament/TenantReviewHeaderDisciplineTest.php
  • T015 [P] [US2] Extend evidence refresh-versus-expire, authorization, and audit coverage in apps/platform/tests/Feature/Evidence/EvidenceSnapshotResourceTest.php and apps/platform/tests/Feature/Evidence/EvidenceSnapshotAuditLogTest.php

Implementation for User Story 2

  • T016 [P] [US2] Align review lifecycle reason propagation, audit prose, and notification wording in apps/platform/app/Services/TenantReviews/TenantReviewLifecycleService.php
  • T017 [US2] Refactor review detail actions so publish and archive follow the catalog while export and create-next stay outside governance friction in apps/platform/app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php
  • T018 [P] [US2] Align evidence lifecycle reason propagation, audit prose, and notification wording in apps/platform/app/Services/Evidence/EvidenceSnapshotService.php
  • T019 [US2] Refactor evidence list and detail actions so refresh remains F1 and expire follows governed lifecycle rules in apps/platform/app/Filament/Resources/EvidenceSnapshotResource.php and apps/platform/app/Filament/Resources/EvidenceSnapshotResource/Pages/ViewEvidenceSnapshot.php

Checkpoint: Review and evidence lifecycle actions are independently functional and semantically distinct from technical refresh or export actions.


Phase 5: User Story 3 - Intervene on Runs with Calibrated Severity (Priority: P2)

Goal: Make retry, mark investigated, and cancel communicate different seriousness on triage-owned run surfaces while preserving calm monitoring context elsewhere.

Independent Test: Open the system run detail page and the tenantless run viewer, then confirm retry stays lighter than mark investigated and cancel, while the tenantless viewer does not promote undocumented triage actions.

Tests for User Story 3

Note

: Write these tests first and confirm they fail before implementation.

  • T020 [P] [US3] Extend system run triage severity, reason, and authorization coverage in apps/platform/tests/Feature/Operations/SystemRunBlockedExecutionNotificationTest.php and apps/platform/tests/Feature/RunAuthorizationTenantIsolationTest.php
  • T021 [P] [US3] Extend calm-surface and no-triage-regression coverage in apps/platform/tests/Feature/Operations/TenantlessOperationRunViewerTest.php

Implementation for User Story 3

  • T022 [US3] Align run-triage reason propagation, audit verbs, and operator copy in apps/platform/app/Services/SystemConsole/OperationRunTriageService.php
  • T023 [US3] Refactor the system run header actions so retry, mark investigated, and cancel use calibrated friction, danger, and placement from the catalog in apps/platform/app/Filament/System/Pages/Ops/ViewRun.php
  • T024 [US3] Review the tenantless viewer and keep it context-first unless a documented governance binding is required in apps/platform/app/Filament/Pages/Operations/TenantlessOperationRunViewer.php

Checkpoint: Run triage is independently functional on the system surface without leaking high-friction semantics onto the calm tenantless viewer.


Phase 6: User Story 4 - Keep Tenant Lifecycle Clear Without Inflating All Actions (Priority: P3)

Goal: Keep archive and restore consistent across tenant view and edit surfaces without over-hardening lower-risk lifecycle moves.

Independent Test: Open the tenant view and edit surfaces for active and archived tenants, then confirm archive and restore use the same vocabulary, confirm depth, and danger rules on both pages.

Tests for User Story 4

Note

: Write these tests first and confirm they fail before implementation.

  • T025 [P] [US4] Extend tenant lifecycle visibility, naming, and authorization coverage in apps/platform/tests/Feature/Rbac/TenantLifecycleActionVisibilityTest.php, apps/platform/tests/Feature/Rbac/TenantLifecycleActionNamingTest.php, apps/platform/tests/Feature/Rbac/TenantResourceAuthorizationTest.php, and apps/platform/tests/Feature/Rbac/EditTenantArchiveUiEnforcementTest.php
  • T026 [P] [US4] Extend tenant lifecycle audit and cross-surface presentation coverage in apps/platform/tests/Feature/Audit/TenantLifecycleAuditLogTest.php and apps/platform/tests/Feature/Filament/TenantLifecyclePresentationAcrossTenantSurfacesTest.php

Implementation for User Story 4

  • T027 [US4] Refactor tenant lifecycle action definitions to bind archive and restore to the shared catalog in apps/platform/app/Filament/Resources/TenantResource.php
  • T028 [US4] Refactor tenant view and edit page lifecycle actions so archive and restore stay aligned across both surfaces in apps/platform/app/Filament/Resources/TenantResource/Pages/ViewTenant.php and apps/platform/app/Filament/Resources/TenantResource/Pages/EditTenant.php

Checkpoint: Tenant lifecycle actions are independently functional and consistent across both workspace tenant surfaces.


Phase 7: Polish & Cross-Cutting Concerns

Purpose: Finish the remaining finding-lifecycle alignment, lock in browser proof, and run focused verification.

  • T029 [P] Add finding lifecycle header-, row-, and bulk-action, navigation-separation, destructive-confirmation, authorization, and audit coverage in apps/platform/tests/Feature/Findings/FindingWorkflowViewActionsTest.php, apps/platform/tests/Feature/Findings/FindingWorkflowRowActionsTest.php, apps/platform/tests/Feature/Findings/FindingBulkActionsTest.php, apps/platform/tests/Feature/Findings/FindingWorkflowUiEnforcementTest.php, apps/platform/tests/Feature/Findings/FindingRbacTest.php, and apps/platform/tests/Feature/Findings/FindingAuditLogTest.php
  • T030 [P] Add cross-surface browser smoke coverage for exception, review, evidence, run, and tenant lifecycle semantics in apps/platform/tests/Browser/Spec194GovernanceFrictionSmokeTest.php
  • T031 Refactor finding lifecycle header, row, and bulk actions so close and reopen follow the catalog while request-exception stays navigation into governance in apps/platform/app/Filament/Resources/FindingResource.php, apps/platform/app/Filament/Resources/FindingResource/Pages/ViewFinding.php, and apps/platform/app/Services/Findings/FindingWorkflowService.php
  • T032 Review mutation-scope wording, explicit confirmation copy for destructive families, canonical labels, notifications, indirect risk-acceptance continuity, and documented deviations in apps/platform/app/Support/Ui/GovernanceActions/GovernanceActionCatalog.php, apps/platform/app/Filament/Pages/Monitoring/FindingExceptionsQueue.php, apps/platform/app/Filament/Resources/FindingExceptionResource/Pages/ViewFindingException.php, apps/platform/app/Filament/Resources/TenantReviewResource/Pages/ViewTenantReview.php, apps/platform/app/Filament/Resources/EvidenceSnapshotResource/Pages/ViewEvidenceSnapshot.php, apps/platform/app/Filament/System/Pages/Ops/ViewRun.php, and apps/platform/app/Filament/Resources/TenantResource.php
  • T033 Run the focused Sail verification workflow from specs/194-governance-friction-hardening/quickstart.md against the changed unit, feature, RBAC, audit, and browser tests in apps/platform/tests/
  • T034 Run formatting with cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent for the changed files in apps/platform/app/ and apps/platform/tests/

Dependencies & Execution Order

Phase Dependencies

  • Setup (Phase 1): No dependencies; can start immediately.
  • Foundational (Phase 2): Depends on Setup completion; blocks all user stories.
  • User Story 1 (Phase 3): Depends on Foundational completion; recommended MVP cut.
  • User Story 2 (Phase 4): Depends on Foundational completion; can run in parallel with US1 after the shared catalog is stable.
  • User Story 3 (Phase 5): Depends on Foundational completion; can run in parallel with US1 or US2 once the run family keys exist in the catalog.
  • User Story 4 (Phase 6): Depends on Foundational completion; can run in parallel with US2 or US3 because it touches separate tenant lifecycle files.
  • Polish (Phase 7): Depends on the desired user stories being complete; it closes the remaining finding lifecycle requirement and final regression proof.

User Story Dependencies

  • US1: No dependencies beyond Foundational.
  • US2: No dependencies beyond Foundational, but it reuses the catalog and guard patterns established for US1.
  • US3: No dependencies beyond Foundational, but it reuses the same reason and danger semantics contract.
  • US4: No dependencies beyond Foundational; it consumes the shared lifecycle rules after the catalog exists.

Within Each User Story

  • Write the story tests first and confirm they fail before implementation.
  • Update the owning service before finalizing the matching page actions when reason propagation or audit wording changes.
  • Keep each story independently shippable before widening the slice.

Parallel Opportunities

  • T002 and T003 can run in parallel after T001.
  • T004, T005, T006, and T007 can run in parallel before T008.
  • Within US1, T009 and T010 can run in parallel.
  • Within US2, T014 and T015 can run in parallel, and T016 and T018 can run in parallel.
  • Within US3, T020 and T021 can run in parallel.
  • Within US4, T025 and T026 can run in parallel.
  • Within Phase 7, T029 and T030 can run in parallel once all page-level story work is complete.

Parallel Example: User Story 1

# Parallel test pass for US1
T009 Extend queue selection-state, modal friction, and reason-prompt coverage
T010 Extend exception lifecycle, authorization, header-discipline, and audit coverage

Parallel Example: User Story 2

# Parallel story work for US2
T014 Extend tenant review lifecycle, export separation, authorization, and audit coverage
T015 Extend evidence refresh-versus-expire, authorization, and audit coverage
T016 Align review lifecycle reason propagation, audit prose, and notification wording
T018 Align evidence lifecycle reason propagation, audit prose, and notification wording

Parallel Example: User Story 3

# Parallel test pass for US3
T020 Extend system run triage severity, reason, and authorization coverage
T021 Extend calm-surface and no-triage-regression coverage

Parallel Example: User Story 4

# Parallel test pass for US4
T025 Extend tenant lifecycle visibility, naming, and authorization coverage
T026 Extend tenant lifecycle audit and cross-surface presentation coverage

Implementation Strategy

MVP First (User Story 1 Only)

  1. Complete Phase 1: Setup.
  2. Complete Phase 2: Foundational catalog and guard work.
  3. Complete Phase 3: User Story 1.
  4. Validate the exception-family behavior through the focused US1 tests.
  5. Stop and review the shared catalog shape before widening the slice.

Incremental Delivery

  1. Ship US1 to establish the first remediated governance family.
  2. Add US2 to normalize review and evidence lifecycle semantics.
  3. Add US3 to calibrate run triage without destabilizing calm monitoring surfaces.
  4. Add US4 to finish tenant lifecycle alignment.
  5. Finish with Phase 7 to align finding lifecycle, add browser proof, and run focused verification.

Parallel Team Strategy

  1. One contributor completes Setup and Foundational tasks.
  2. After Foundation is green:
    • Contributor A takes US1.
    • Contributor B takes US2.
    • Contributor C takes US3.
    • Contributor D takes US4.
  3. Merge back for Phase 7 finding-lifecycle alignment, browser smoke, and verification.