TenantAtlas/specs/134-audit-log-foundation/tasks.md
ahmido 28cfe38ba4 feat: lay audit log foundation (#163)
## Summary
- turn the Monitoring audit log placeholder into a real workspace-scoped audit review surface
- introduce a shared audit recorder, richer audit value objects, and additive audit log schema evolution
- add audit outcome and actor badges, permission-aware related navigation, and durable audit retention coverage

## Included
- canonical `/admin/audit-log` list and detail inspection UI
- audit model helpers, taxonomy expansion, actor/target snapshots, and recorder/builder services
- operation terminal audit writes and purge command retention changes
- spec 134 design artifacts and focused Pest coverage for audit foundation behavior

## Validation
- `vendor/bin/sail bin pint --dirty --format agent`
- `vendor/bin/sail artisan test --compact tests/Unit/Audit tests/Unit/Badges/AuditBadgesTest.php tests/Feature/Filament/AuditLogPageTest.php tests/Feature/Filament/AuditLogDetailInspectionTest.php tests/Feature/Filament/AuditLogAuthorizationTest.php tests/Feature/Monitoring/AuditCoverageGovernanceTest.php tests/Feature/Monitoring/AuditCoverageOperationsTest.php tests/Feature/Console/TenantpilotPurgeNonPersistentDataTest.php`

## Notes
- Livewire v4.0+ compliance is preserved within the existing Filament v5 application.
- No provider registration changes were needed; panel provider registration remains in `bootstrap/providers.php`.
- No new globally searchable resource was introduced.
- The audit page remains read-only; no destructive actions were added.
- No new asset pipeline changes were introduced; existing deploy-time `php artisan filament:assets` behavior remains unchanged.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #163
2026-03-11 09:39:37 +00:00

19 KiB
Raw Permalink Blame History

Tasks: Audit Log Foundation

Input: Design documents from /specs/134-audit-log-foundation/ Prerequisites: plan.md, spec.md, research.md, data-model.md, contracts/audit-log-review.openapi.yaml, quickstart.md

Tests: Tests are REQUIRED for this feature because it changes runtime behavior across existing audit persistence, workflow instrumentation, and Filament Monitoring surfaces.

Phase 1: Setup (Shared Infrastructure)

Purpose: Create the shared implementation and test entry points used by all story work.

  • T001 Create the audit unit-test entry points in tests/Unit/Audit/AuditActionIdTest.php, tests/Unit/Audit/AuditRecorderTest.php, tests/Unit/Audit/AuditLogCompatibilityTest.php, and tests/Unit/Audit/AuditContextSanitizerTest.php
  • T002 Create the audit feature-test entry points in tests/Feature/Filament/AuditLogPageTest.php, tests/Feature/Filament/AuditLogDetailInspectionTest.php, tests/Feature/Filament/AuditLogAuthorizationTest.php, tests/Feature/Monitoring/AuditCoverageGovernanceTest.php, tests/Feature/Monitoring/AuditCoverageOperationsTest.php, and tests/Feature/Console/TenantpilotPurgeNonPersistentDataTest.php
  • T003 Create the shared audit support entry points in app/Support/Audit/AuditActorType.php, app/Support/Audit/AuditOutcome.php, app/Support/Audit/AuditActorSnapshot.php, app/Support/Audit/AuditTargetSnapshot.php, app/Services/Audit/AuditRecorder.php, and app/Services/Audit/AuditEventBuilder.php

Phase 2: Foundational (Blocking Prerequisites)

Purpose: Build the first-class audit schema, taxonomy, recorder, and retention rules before any user story work begins.

⚠️ CRITICAL: No user story work can begin until this phase is complete.

  • T004 Add additive audit-log evolution migrations in database/migrations/ to introduce summary, outcome, actor-type, actor-label, target-label, operation-run linkage, compatibility backfills, and the minimum review indexes for workspace plus recorded-at, tenant plus recorded-at, normalized action, and normalized outcome queries
  • T005 [P] Update app/Models/AuditLog.php to expose the new casts, scope helpers, relation shortcuts, summary fallbacks, and immutable read semantics for legacy and new audit rows
  • T006 [P] Expand the audit taxonomy and value objects in app/Support/Audit/AuditActionId.php, app/Support/Audit/AuditActorType.php, app/Support/Audit/AuditOutcome.php, app/Support/Audit/AuditActorSnapshot.php, and app/Support/Audit/AuditTargetSnapshot.php
  • T007 [P] Implement the shared recorder foundation in app/Services/Audit/AuditRecorder.php and app/Services/Audit/AuditEventBuilder.php so actor, target, summary, outcome, and context shaping flow through one reusable write path
  • T008 [P] Tighten redaction and context-shaping rules in app/Support/Audit/AuditContextSanitizer.php and any supporting helpers it depends on so secrets, tokens, and oversized payloads never persist to audit rows
  • T009 Update app/Services/Audit/WorkspaceAuditLogger.php, app/Services/Intune/AuditLogger.php, and app/Services/SystemConsole/SystemConsoleAuditLogger.php to wrap the shared recorder without breaking existing callers
  • T010 Update app/Console/Commands/TenantpilotPurgeNonPersistentData.php so v1 audit history remains durable and is no longer purged as non-persistent workspace noise
  • T011 [P] Add foundational schema, taxonomy, recorder, compatibility, and retention coverage in tests/Unit/Audit/AuditActionIdTest.php, tests/Unit/Audit/AuditRecorderTest.php, tests/Unit/Audit/AuditLogCompatibilityTest.php, tests/Unit/Audit/AuditContextSanitizerTest.php, and tests/Feature/Console/TenantpilotPurgeNonPersistentDataTest.php

Checkpoint: The audit event store, shared recorder, and retention posture are ready; user-story work can now begin.


Phase 3: User Story 1 - Review What Happened In The Environment (Priority: P1) 🎯 MVP

Goal: Replace the placeholder audit page with a summary-first, reverse-chronological Monitoring surface backed by meaningful governance and administration audit coverage.

Independent Test: Trigger covered governance and admin actions, open /admin/audit-log, and verify the page shows readable rows with actor, summary, target, timestamp, and outcome without opening row details. This story is functionally testable on its own, but it is not release-safe until the authorization and tenant-boundary tasks in T027-T029 are also complete.

Tests for User Story 1

  • T012 [P] [US1] Add canonical list rendering, reverse-chronological ordering, summary-field search, tenant-context default-filter preselection, empty-state, and placeholder-removal coverage in tests/Feature/Filament/AuditLogPageTest.php
  • T013 [P] [US1] Add governance and admin audit-emission coverage for finding status and assignment changes, risk-acceptance lifecycle events, baseline profile create or update or status-change events, baseline capture and compare started or completed or failed events, membership changes, settings changes, onboarding acknowledgements, verification acknowledgements, and alert configuration changes in tests/Feature/Monitoring/AuditCoverageGovernanceTest.php

Implementation for User Story 1

  • T014 [P] [US1] Instrument finding lifecycle and risk-acceptance audit writes in app/Services/Findings/FindingWorkflowService.php using the shared recorder and normalized audit taxonomy
  • T015 [P] [US1] Instrument baseline profile create or update or status-change audit writes plus baseline capture and compare started or completed or failed audit writes in app/Services/Baselines/BaselineCaptureService.php, app/Services/Baselines/BaselineCompareService.php, app/Services/Baselines/BaselineEvidenceCaptureResumeService.php, app/Jobs/CaptureBaselineSnapshotJob.php, and app/Jobs/CompareBaselineToTenantJob.php
  • T016 [P] [US1] Normalize workspace-admin audit writes in app/Services/Auth/WorkspaceMembershipManager.php, app/Services/Settings/SettingsWriter.php, app/Http/Controllers/TenantOnboardingController.php, app/Services/Intune/RbacOnboardingService.php, app/Services/Verification/VerificationCheckAcknowledgementService.php, app/Filament/Resources/AlertRuleResource.php, and app/Filament/Resources/AlertDestinationResource.php so actor, target, summary, and outcome semantics match the new audit contract
  • T017 [P] [US1] Add audit outcome and actor-kind badge support in app/Support/Badges/BadgeDomain.php, app/Support/Badges/BadgeCatalog.php, and any badge-mapping tests that cover the new audit values
  • T018 [US1] Replace the placeholder Monitoring surface in app/Filament/Pages/Monitoring/AuditLog.php and resources/views/filament/pages/monitoring/audit-log.blade.php with a summary-first workspace-scoped audit table that uses the evolved AuditLog model and exposes search over high-signal summary fields
  • T019 [US1] Add audit list filter, active-tenant default preselection, and date-range option sources in app/Support/Filament/FilterOptionCatalog.php and app/Support/Filament/FilterPresets.php so the page can filter by outcome, event type, actor, target type, tenant, and time range within the current workspace only

Checkpoint: User Story 1 is complete when /admin/audit-log is a working summary-first history surface for covered governance and admin events.


Phase 4: User Story 2 - Inspect An Event In Context (Priority: P2)

Goal: Let operators inspect one audit event in a readable detail surface and open the affected resource when the target still exists and they are entitled to view it.

Independent Test: Open a covered audit row, verify the detail surface emphasizes summary, actor, target, scope, outcome, and readable context, and confirm the related link appears only when the resource exists and the viewer is allowed to open it.

Tests for User Story 2

  • T020 [P] [US2] Add audit detail rendering and related-link behavior coverage in tests/Feature/Filament/AuditLogDetailInspectionTest.php
  • T021 [P] [US2] Add backup create or update or archive coverage, restore initiation or completion or failure coverage, operation retry or rerun coverage, and Ops-UX regression coverage in tests/Feature/Monitoring/AuditCoverageOperationsTest.php, tests/Feature/OpsUx/Regression/RestoreRunTerminalNotificationTest.php, tests/Feature/OpsUx/Regression/BackupScheduleRunNotificationTest.php, tests/Feature/OpsUx/QueuedToastCopyTest.php, and tests/Feature/OpsUx/Constitution/JobDbNotificationGuardTest.php

Implementation for User Story 2

  • T022 [P] [US2] Instrument backup set creation, update, archive, and retention workflow audit writes in app/Services/Intune/BackupService.php, app/Services/AssignmentBackupService.php, app/Jobs/RunBackupScheduleJob.php, and app/Jobs/ApplyBackupScheduleRetentionJob.php
  • T023 [P] [US2] Instrument restore initiation, completion, failure, and partial-outcome audit writes in app/Services/Intune/RestoreService.php, app/Services/AssignmentRestoreService.php, app/Jobs/ExecuteRestoreRunJob.php, and app/Jobs/RestoreAssignmentsJob.php
  • T024 [P] [US2] Instrument high-value operation completion, failure, retry, and rerun audit writes alongside existing run ownership in app/Services/OperationRunService.php, app/Support/OpsUx/OperationUxPresenter.php, app/Notifications/OperationRunCompleted.php, app/Jobs/BulkBackupSetRestoreJob.php, app/Jobs/BulkRestoreRunRestoreJob.php, and app/Jobs/BulkPolicyVersionRestoreJob.php without introducing ad-hoc toasts, direct status/outcome transitions, or custom terminal DB notifications
  • T025 [P] [US2] Add permission-aware audit target destinations in app/Support/Navigation/RelatedNavigationResolver.php so audit entries can resolve canonical links without leaking inaccessible targets
  • T026 [US2] Extend app/Filament/Pages/Monitoring/AuditLog.php and resources/views/filament/pages/monitoring/audit-log.blade.php with event inspection, readable context sections, technical metadata fallback, target drill-down affordances, and DB-only render behavior that never triggers remote calls during list or detail rendering

Checkpoint: User Story 2 is complete when operators can inspect an event in context and open a permitted target without leaving the canonical audit workflow blindly.


Phase 5: User Story 3 - Trust Scope And Access Boundaries (Priority: P3)

Goal: Enforce workspace membership, audit.view, tenant scoping, and permission-aware target visibility so the audit surface never leaks cross-workspace or cross-tenant evidence.

Independent Test: Exercise /admin/audit-log and event-detail inspection as a non-member, a workspace member without audit.view, and a scoped operator with partial tenant entitlements, then confirm 404 vs 403 semantics, row visibility, filter options, and related-link behavior all match the spec.

Tests for User Story 3

  • T027 [P] [US3] Add positive and negative authorization coverage for canonical audit list and detail access in tests/Feature/Filament/AuditLogAuthorizationTest.php
  • T028 [P] [US3] Add legacy-reader and hidden-target compatibility coverage in tests/Unit/Audit/AuditLogCompatibilityTest.php and tests/Feature/Filament/AuditLogDetailInspectionTest.php

Implementation for User Story 3

  • T029 [US3] Enforce workspace membership, audit.view, deny-as-not-found tenant scoping, and tenant-safe filter option queries in app/Filament/Pages/Monitoring/AuditLog.php using app/Support/Auth/Capabilities.php and existing workspace or tenant authorization helpers
  • T030 [US3] Harden target-link suppression and target-label fallback behavior in app/Support/Navigation/RelatedNavigationResolver.php and app/Models/AuditLog.php so inaccessible or deleted resources remain intelligible without leaking links or hints
  • T031 [US3] Preserve compatibility for existing audit readers in app/Filament/System/Pages/Security/AccessLogs.php, app/Filament/System/Pages/RepairWorkspaceOwners.php, app/Console/Commands/TenantpilotPurgeNonPersistentData.php, and app/Services/SystemConsole/SystemConsoleAuditLogger.php while the richer schema rolls out

Checkpoint: User Story 3 is complete when audit visibility obeys the same workspace and tenant boundaries as the rest of the product and older readers still work safely.


Phase 6: Polish & Cross-Cutting Concerns

Purpose: Lock in naming consistency, cross-story regression coverage, and final verification.

  • T032 [P] Update operator-facing summaries, empty-state copy, detail headings, and related-link labels in app/Filament/Pages/Monitoring/AuditLog.php, resources/views/filament/pages/monitoring/audit-log.blade.php, and app/Support/Audit/AuditActionId.php to align with UI-NAMING-001 domain-first wording
  • T033 [P] Add cross-story regression coverage for badge mappings, placeholder removal, immutable UI behavior, permission-aware target navigation, and custom-page Action Surface or UX-001 compliance in tests/Feature/Filament/AuditLogPageTest.php, tests/Feature/Filament/AuditLogDetailInspectionTest.php, tests/Feature/Filament/AuditLogAuthorizationTest.php, and tests/Feature/Guards/ActionSurfaceContractTest.php
  • T034 Run the focused validation commands documented in specs/134-audit-log-foundation/quickstart.md
  • T035 Run formatting on touched files with vendor/bin/sail bin pint --dirty --format agent from /Users/ahmeddarrazi/Documents/projects/TenantAtlas

Dependencies & Execution Order

Phase Dependencies

  • Setup (Phase 1): No dependencies; can start immediately.
  • Foundational (Phase 2): Depends on Setup completion; blocks all user-story implementation.
  • User Stories (Phases 3-5): Depend on Foundational completion.
  • Polish (Phase 6): Depends on the desired user stories being complete.

User Story Dependencies

  • User Story 1 (P1): Starts after Foundational and delivers the functional MVP surface by making /admin/audit-log a real summary-first Monitoring page with first-wave governance and admin coverage.
  • User Story 2 (P2): Starts after Foundational and builds on US1s list surface to add inspection, backup or restore coverage, and permission-aware related links.
  • User Story 3 (P3): Starts after Foundational and must be completed before release because authorization, tenant scoping, and compatibility are baseline safety requirements for the canonical audit surface, not optional post-MVP hardening.

Within Each User Story

  • Write or update the story tests first and confirm they fail against the pre-change behavior.
  • Land domain instrumentation before finalizing the page behavior that surfaces the resulting events.
  • Keep badge, filter, and related-navigation helpers shared rather than page-local.
  • Finish story-level validation before moving to the next priority.

Parallel Opportunities

  • T005 through T008 can run in parallel after T004, then T009 through T011 complete the foundational layer.
  • In US1, T012 and T013 can run in parallel, then T014 through T017 can split by domain before T018 and T019 finalize the page surface.
  • In US2, T020 and T021 can run in parallel, then T022 through T025 can split by workflow and navigation before T026 integrates the detail experience.
  • In US3, T027 and T028 can run in parallel, then T029 through T031 harden authorization, fallback, and reader compatibility.
  • T032 and T033 can run in parallel once the user-story phases are complete.

Parallel Example: User Story 1

# Launch the US1 test updates together:
Task: "Add canonical list rendering, reverse-chronological ordering, empty-state, and placeholder-removal coverage in tests/Feature/Filament/AuditLogPageTest.php"
Task: "Add governance and admin audit-emission coverage for findings, baselines, membership, and settings changes in tests/Feature/Monitoring/AuditCoverageGovernanceTest.php"

# Split the domain instrumentation work:
Task: "Instrument finding lifecycle audit writes in app/Services/Findings/FindingWorkflowService.php using the shared recorder and normalized audit taxonomy"
Task: "Instrument baseline capture and compare audit writes in app/Services/Baselines/BaselineCaptureService.php, app/Services/Baselines/BaselineCompareService.php, app/Services/Baselines/BaselineEvidenceCaptureResumeService.php, app/Jobs/CaptureBaselineSnapshotJob.php, and app/Jobs/CompareBaselineToTenantJob.php"
Task: "Normalize workspace-admin audit writes in app/Services/Auth/WorkspaceMembershipManager.php and app/Services/Settings/SettingsWriter.php so actor, target, summary, and outcome semantics match the new audit contract"

Parallel Example: User Story 2

# Launch the US2 test updates together:
Task: "Add audit detail rendering and related-link behavior coverage in tests/Feature/Filament/AuditLogDetailInspectionTest.php"
Task: "Add backup, restore, and operation-outcome audit-emission coverage in tests/Feature/Monitoring/AuditCoverageOperationsTest.php"

# Split the workflow instrumentation work:
Task: "Instrument backup workflow audit writes in app/Services/Intune/BackupService.php, app/Services/AssignmentBackupService.php, app/Jobs/RunBackupScheduleJob.php, and app/Jobs/ApplyBackupScheduleRetentionJob.php"
Task: "Instrument restore workflow audit writes in app/Services/Intune/RestoreService.php, app/Services/AssignmentRestoreService.php, app/Jobs/ExecuteRestoreRunJob.php, and app/Jobs/RestoreAssignmentsJob.php"
Task: "Instrument high-value operation completion, failure, and retry audit writes alongside existing run ownership in app/Services/OperationRunService.php, app/Jobs/BulkBackupSetRestoreJob.php, app/Jobs/BulkRestoreRunRestoreJob.php, and app/Jobs/BulkPolicyVersionRestoreJob.php"

Implementation Strategy

MVP First (User Story 1 Only)

  1. Complete Phase 1: Setup.
  2. Complete Phase 2: Foundational.
  3. Complete Phase 3: User Story 1.
  4. Complete T027-T029 from User Story 3 to enforce mandatory authorization and tenant-boundary rules before any release candidate exists.
  5. Validate /admin/audit-log against the US1 independent test plus the US3 authorization checks before moving on.

Incremental Delivery

  1. Finish Setup and Foundational shared audit infrastructure.
  2. Deliver User Story 1 to establish the canonical audit history surface.
  3. Deliver User Story 2 to add inspection and deeper operational context.
  4. Deliver User Story 3 before release so authorization, tenant boundaries, and compatibility are in place for all exposed audit flows.
  5. Finish with naming cleanup, regression coverage, validation commands, and formatting.

Parallel Team Strategy

  1. One contributor handles the migration/model/recorder foundation while another prepares the unit and feature tests.
  2. After Foundation is ready, split US1 and US2 domain instrumentation across findings, baselines, backup, restore, and operations workflows.
  3. Reserve one contributor for the Filament page and authorization hardening once the event-producing workflows are emitting the expected audit records.

Notes

  • [P] tasks touch different files and can be executed in parallel.
  • User-story labels map directly to the prioritized stories in spec.md.
  • Tests are mandatory in this repo for every runtime change in the resulting implementation.
  • The suggested MVP scope is Phase 3 only after Setup and Foundational are complete.