# Implementation Plan: 094 Assignment Operations Observability Hardening **Branch**: `094-assignment-ops-observability-hardening` | **Date**: 2026-02-15 | **Spec**: [spec.md](spec.md) **Input**: Feature specification from [spec.md](spec.md) ## Summary This work hardens ship-safety by making assignment fetch/restore executions fully observable in Monitoring (via `OperationRun`), improving Graph testability by using the Graph client interface, and closing a small set of authorization inconsistencies (cross-plane guard leak, policy bypass, and 404/403 ordering). ## Technical Context **Language/Version**: PHP 8.4 (Laravel 12) **Primary Dependencies**: Filament v5, Livewire v4, Laravel Sail, Microsoft Graph integration **Storage**: PostgreSQL (Sail) **Testing**: Pest v4 (`./vendor/bin/sail artisan test`) **Target Platform**: Linux container runtime (Sail/Dokploy) **Project Type**: Laravel web application (admin UI via Filament) **Performance Goals**: Monitoring pages must remain DB-only and render quickly (no external calls during render). **Constraints**: No secrets/tokens in logs or run failures; RBAC-UX semantics must match constitution (404 vs 403). **Scale/Scope**: Small hardening change set; no new domain entities; focused on two jobs + a few UI/policy surfaces. ## Constitution Check *GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* - Inventory-first: PASS (no inventory semantics changed). - Read/write separation: PASS (restore remains a user-triggered operation; change is observability/auditability). - Graph contract path: PASS-BY-DESIGN (plan includes removing concrete client injections in assignment-related services). - Deterministic capabilities: PASS (no new capability model; micro-fixes ensure enforcement uses canonical patterns). - RBAC-UX planes: PASS (plan includes closing remaining cross-plane guard leak; non-member 404, member missing capability 403). - Workspace isolation: PASS (operations remain tenant-bound; Monitoring remains DB-only). - Destructive confirmations: PASS (no new destructive actions added; enforcement fixes must preserve confirmations). - Global search safety: N/A (no global search changes). - Tenant isolation: PASS (no cross-tenant views added; monitoring surfaces already entitlement-checked). - Run observability: PASS-BY-DESIGN (this spec exists to bring remaining assignment jobs under `OperationRun`). - Automation: PASS (dedupe identity clarified; existing partial unique index patterns used). - Data minimization: PASS (failures must be sanitized; no raw payloads stored). - Badge semantics: N/A (no badge mapping changes). - Filament UI Action Surface Contract: PASS (no new resources; micro-fixes must not remove inspect affordances). ## Project Structure ### Documentation (this feature) ```text specs/094-assignment-ops-observability-hardening/ ├── plan.md ├── spec.md ├── tasks.md ├── research.md ├── data-model.md ├── quickstart.md ├── contracts/ │ └── assignment-ops.openapi.yaml └── checklists/ └── requirements.md ``` ### Source Code (repository root) ```text app/ ├── Jobs/ │ ├── FetchAssignmentsJob.php │ ├── RestoreAssignmentsJob.php │ └── Middleware/TrackOperationRun.php ├── Services/ │ ├── OperationRunService.php │ ├── AssignmentBackupService.php │ ├── AssignmentRestoreService.php │ └── Graph/ │ ├── GraphClientInterface.php │ ├── MicrosoftGraphClient.php │ ├── NullGraphClient.php │ ├── AssignmentFetcher.php │ ├── AssignmentFilterResolver.php │ └── GroupResolver.php ├── Filament/ │ └── Resources/... └── Http/ └── Middleware/EnsureCorrectGuard.php routes/ └── web.php tests/ ├── Feature/ └── Unit/ ``` **Structure Decision**: Use the existing Laravel structure; changes are limited to the job layer, Graph service DI, a few Filament surfaces, and targeted Pest tests. ## Phase 0 — Outline & Research Artifacts: - [research.md](research.md) Research outcomes (resolved decisions): - Operation run identity & dedupe: tenant + type + target/scope. - Counters semantics: total attempted, processed succeeded, failed failed. - Failure convention: operation-specific `code` + normalized `reason_code`. - Audit log granularity: exactly one entry per restore execution. ## Phase 1 — Design & Contracts Artifacts: - [data-model.md](data-model.md) - [contracts/assignment-ops.openapi.yaml](contracts/assignment-ops.openapi.yaml) - [quickstart.md](quickstart.md) Design notes: - No new persistent entities. - Operation run tracking must use existing dedupe/index patterns. - Monitoring surfaces remain DB-only. ## Phase 1 — Agent Context Update Run: - `.specify/scripts/bash/update-agent-context.sh copilot` ## Phase 1 — Constitution Check (re-evaluation) Re-check result: PASS expected once implementation removes concrete Graph client injections and adds OperationRun tracking for the two remaining assignment jobs. ## Phase 2 — Implementation Plan ### Step 1 — OperationRun tracking for assignment fetch/restore - Locate job dispatch/start surfaces. - Ensure each execution creates/reuses an `OperationRun`: - Dedupe identity: - Fetch: tenant + type + backup item (or equivalent policy-version identifier). - Restore: tenant + type + restore run identifier. - Ensure Tracking middleware is applied and the job exposes a run handle per existing conventions. - Ensure failure details: - `code`: operation-specific namespace. - `reason_code`: normalized cause. - message: sanitized. - Ensure counters match the agreed semantics. ### Step 2 — Audit log for assignment restore execution - Ensure exactly one audit log entry is written per assignment restore execution. ### Step 3 — Graph client interface enforcement - Update assignment-related services to accept the Graph client interface. ### Step 4 — Authorization micro-fixes - Close cross-plane guard leak on workspace-scoped admin routes. - Remove any policy bypasses on Provider Connections list surfaces. - Fix membership (404) vs capability (403) ordering for backup item surfaces. - Ensure legacy UI enforcement helpers are not used where the canonical helper exists. ### Step 5 — Tests + formatting - Add targeted Pest regression coverage for: - operation run tracking (success/failure) - guard leak - policy enforcement - 404/403 ordering - Graph interface mockability - Run `./vendor/bin/sail bin pint --dirty`. - Run targeted tests then widen as needed. ## Complexity Tracking No constitution violations are required for this feature.