# Tasks: Operations Auto-Refresh Pass

**Input**: Design documents from `/specs/123-operations-auto-refresh/`  
**Prerequisites**: plan.md, spec.md, research.md, data-model.md, contracts/polling-contracts.yaml, quickstart.md

**Tests**: Tests are REQUIRED for this runtime behavior change. Use Pest feature tests via Sail.  
**Operations**: No new `OperationRun` type or lifecycle work is required for this feature; tasks must reuse existing `OperationRun` observability semantics and preserve the existing tenantless Monitoring route.  
**RBAC**: No authorization model changes are planned; tasks must preserve existing workspace membership checks for the tenantless run viewer and existing tenant capability checks for every tenant-scoped host surface that renders the review pack card.  
**Filament UI Action Surfaces**: The affected Filament surfaces change passive refresh behavior only; no new actions, destructive flows, or action-matrix rows are introduced beyond the approved spec exemption.  
**Filament UI UX-001**: No Create/Edit/View layout changes are required; tasks must preserve existing viewer and card layouts while adding non-noisy auto-refresh behavior.

**Organization**: Tasks are grouped by user story so each story remains independently testable.

## Phase 1: Setup (Shared Context)

**Purpose**: Align implementation with the approved polling contract and current codebase patterns before editing runtime code.

- [X] T001 [P] Review the approved polling behavior in specs/123-operations-auto-refresh/spec.md, specs/123-operations-auto-refresh/research.md, specs/123-operations-auto-refresh/contracts/polling-contracts.yaml, and specs/123-operations-auto-refresh/quickstart.md
- [X] T002 [P] Inspect the current shared polling implementations in app/Support/OpsUx/RunDetailPolling.php, app/Filament/Resources/OperationRunResource.php, app/Filament/Widgets/Dashboard/NeedsAttention.php, and resources/views/filament/widgets/dashboard/needs-attention.blade.php

---

## Phase 2: Foundational (Blocking Prerequisites)

**Purpose**: Confirm the active-vs-terminal state sources that both polling surfaces depend on.

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

- [X] T003 Confirm polling state ownership in app/Support/OpsUx/OperationStatusNormalizer.php, app/Support/ReviewPackStatus.php, app/Models/ReviewPack.php, app/Services/ReviewPackService.php, and app/Jobs/GenerateReviewPackJob.php so active and terminal semantics stay consistent across both surfaces

**Checkpoint**: Shared polling semantics are confirmed and user-story implementation can begin.

---

## Phase 3: User Story 1 - Watch an active operation complete (Priority: P1) 🎯 MVP

**Goal**: Make the tenantless operation run viewer update automatically while a run remains active.

**Independent Test**: Open `/admin/operations/{run}` for queued and running runs and verify the page emits auto-refresh behavior; open the same page for a completed run and verify it does not rely on manual refresh for active monitoring.

### Tests for User Story 1 ⚠️

> **NOTE**: Add or update these tests first and ensure they fail before implementation.

- [X] T004 [P] [US1] Extend tests/Feature/OpsUx/RunDetailPollingStopsOnTerminalTest.php to cover the shared queued/running polling contract and age-based interval expectations in app/Support/OpsUx/RunDetailPolling.php
- [X] T005 [P] [US1] Extend tests/Feature/Operations/TenantlessOperationRunViewerTest.php to assert queued and running runs render polling markup on the `/admin/operations/{run}` viewer while preserving the existing workspace-membership and tenant-entitlement access semantics on that canonical route

### Implementation for User Story 1

- [X] T006 [US1] Ensure app/Filament/Pages/Operations/TenantlessOperationRunViewer.php and resources/views/filament/pages/operations/tenantless-operation-run-viewer.blade.php surface the shared polling contract from app/Filament/Resources/OperationRunResource.php without breaking the existing hidden-tab and mounted-action guards in app/Support/OpsUx/RunDetailPolling.php

**Checkpoint**: User Story 1 should now allow operators to watch active tenantless runs update automatically.

---

## Phase 4: User Story 2 - Monitor review pack generation from the card (Priority: P2)

**Goal**: Make the tenant review pack card refresh itself while generation is queued or in progress.

**Independent Test**: Open any tenant-scoped host surface that renders `TenantReviewPackCard`, trigger review-pack generation, and verify the card refreshes itself until the pack finishes.

### Tests for User Story 2 ⚠️

- [X] T007 [P] [US2] Extend tests/Feature/ReviewPack/ReviewPackWidgetTest.php to assert queued and generating review pack states render `wire:poll.10s` on the card while preserving the widget’s existing tenant membership and review-pack capability behavior
- [X] T008 [P] [US2] Extend tests/Feature/ReviewPack/ReviewPackGenerationTest.php to keep `queued` and `generating` aligned as the only active lifecycle states that should drive card polling

### Implementation for User Story 2

- [X] T009 [US2] Add a review-pack polling interval resolver in app/Filament/Widgets/Tenant/TenantReviewPackCard.php that returns `10s` only when the latest pack status is `queued` or `generating`
- [X] T010 [US2] Apply conditional root-level polling markup in resources/views/filament/widgets/tenant/tenant-review-pack-card.blade.php using the interval exposed by app/Filament/Widgets/Tenant/TenantReviewPackCard.php

**Checkpoint**: User Story 2 should now let users observe review pack generation without manual refresh.

---

## Phase 5: User Story 3 - Avoid noisy refresh behavior on completed work (Priority: P3)

**Goal**: Stop polling cleanly for terminal or unknown states so completed surfaces remain stable.

**Independent Test**: Open completed/failed tenantless runs plus ready/failed/expired/no-pack review card states and confirm none of them emit polling markup or restart refresh loops.

### Tests for User Story 3 ⚠️

- [X] T011 [P] [US3] Extend tests/Feature/Operations/TenantlessOperationRunViewerTest.php to assert completed and failed tenantless runs render without polling markup when loaded directly in a terminal state, without regressing the route’s existing 404 and 403 behavior
- [X] T012 [P] [US3] Extend tests/Feature/ReviewPack/ReviewPackWidgetTest.php to assert ready, failed, expired, and no-pack card states render without polling markup

### Implementation for User Story 3

- [X] T013 [US3] Harden non-active fallback logic in app/Support/OpsUx/RunDetailPolling.php and app/Filament/Widgets/Tenant/TenantReviewPackCard.php so terminal or unrecognized states always resolve to `null` polling without visible UI churn

**Checkpoint**: User Story 3 should now guarantee stable terminal states across both surfaces.

---

## Phase 6: Polish & Cross-Cutting Concerns

**Purpose**: Final verification, manual QA, and formatting across all stories.

- [ ] T014 Perform the manual QA flow from specs/123-operations-auto-refresh/quickstart.md for one active and one terminal tenantless run plus one active and one terminal review pack generation lifecycle
- [X] T015 Run focused Pest coverage with `vendor/bin/sail artisan test --compact` for tests/Feature/OpsUx/RunDetailPollingStopsOnTerminalTest.php, tests/Feature/Operations/TenantlessOperationRunViewerTest.php, tests/Feature/ReviewPack/ReviewPackWidgetTest.php, and tests/Feature/ReviewPack/ReviewPackGenerationTest.php
- [X] T016 Run `vendor/bin/sail bin pint --dirty --format agent`
- [X] T017 Run existing non-regression authorization coverage with `vendor/bin/sail artisan test --compact` for tests/Feature/Operations/TenantlessOperationRunViewerTest.php and tests/Feature/ReviewPack/ReviewPackRbacTest.php to confirm routes, ownership semantics, and access rules remain unchanged

---

## 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; this is the MVP.
- **User Story 2 (Phase 4)**: Depends on Foundational completion; can proceed after US1 or in parallel once shared polling semantics are confirmed.
- **User Story 3 (Phase 5)**: Depends on Foundational completion and benefits from US1/US2 polling hooks being in place.
- **Polish (Phase 6)**: Depends on completion of the desired user stories.

### User Story Dependencies

- **US1**: No dependency on other stories; delivers the primary operator-facing value.
- **US2**: No dependency on US1; it depends only on the shared polling semantics confirmed in Phase 2.
- **US3**: Depends on the active-polling implementation paths from US1 and US2 so terminal-state behavior can be finalized and verified.

### Within Each User Story

- Tests should be added or updated first and observed failing before implementation.
- Shared helper or resolver changes should land before Blade markup changes that consume them.
- Story-specific verification should complete before moving to the next priority.

### Parallel Opportunities

- T001 and T002 can run in parallel.
- T004 and T005 can run in parallel.
- T007 and T008 can run in parallel.
- T011 and T012 can run in parallel.
- After Phase 2, US1 and US2 can be implemented in parallel if different contributors own the run viewer and review pack card.

---

## Parallel Example: User Story 1

```bash
Task: "Extend tests/Feature/OpsUx/RunDetailPollingStopsOnTerminalTest.php to cover the shared queued/running polling contract and age-based interval expectations"
Task: "Extend tests/Feature/Operations/TenantlessOperationRunViewerTest.php to assert queued and running runs render polling markup on the /admin/operations/{run} viewer"
```

---

## Parallel Example: User Story 2

```bash
Task: "Extend tests/Feature/ReviewPack/ReviewPackWidgetTest.php to assert queued and generating review pack states render wire:poll.10s on the card"
Task: "Extend tests/Feature/ReviewPack/ReviewPackGenerationTest.php to keep queued and generating aligned as the only active lifecycle states that should drive card polling"
```

---

## Parallel Example: User Story 3

```bash
Task: "Extend tests/Feature/Operations/TenantlessOperationRunViewerTest.php to assert completed and failed tenantless runs render without polling markup"
Task: "Extend tests/Feature/ReviewPack/ReviewPackWidgetTest.php to assert ready, failed, expired, and no-pack card states render without polling markup"
```

---

## 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. Validate queued and running tenantless operation runs auto-refresh correctly
5. Stop and review before broadening the change to the tenant review pack card if needed

### Incremental Delivery

1. Ship the tenantless run viewer polling improvement in US1
2. Add review pack card polling in US2
3. Harden terminal-state stability and non-active fallback behavior in US3
4. Finish with focused Sail tests, manual QA, and Pint

### Parallel Team Strategy

With multiple contributors:

1. One contributor owns tenantless run viewer tests and implementation (US1)
2. One contributor owns review pack card tests and implementation (US2)
3. One contributor validates terminal/noisy-state regression coverage (US3)
4. Recombine for focused Sail test execution and formatting

---

## Notes

- [P] tasks touch different files and can be executed in parallel.
- User story labels map each task to the corresponding story in spec.md.
- No migrations, no new routes, and no dependency changes are expected.
- Manual QA evidence belongs in review artifacts, not committed files.
