# Incident Lifecycle Controls

audience: AI coding agents first.

status: ACTIVE
task IDs: #13
source request: Add Incidents Actions interface to stop active incident work by killing its active agents; delete incidents only when not currently active; replace text Actions trigger with tools SVG icon; set refresh rate within backend rate limits; push and deploy. Final review repair: treat only `RPC_NULL_RESULT` as bound-task absence; rethrow auth, transport, malformed, backend, and false-result failures; after absence, resolve canonical incident ID again, detect successor reuse, validate project/canonical metadata/state, and atomically quarantine stale intent instead of finalizing it; add focused service regressions for error classification, reused IDs, stale-intent quarantine, marker binding, lease loss, and competing adoption where coverage is missing. Preserve design; surgical changes; no commit. Run focused collector tests and typecheck only through canonical commands; if remote-only dispatch refuses, report exact refusal and do not run locally; run `git diff --check`.

## Outcome

Ship owner-visible lifecycle controls on `/incidents`: stop active work safely, delete inactive records safely, compact tools-icon Actions trigger, and backend-safe refresh behavior.

## Acceptance criteria

- Active incident Actions exposes Stop work. Stop targets only agent process/unit bound to that incident and returns authoritative refreshed state.
- Inactive incident Actions exposes Delete. Backend MUST reject deletion when incident is active, including state changes racing UI.
- UI NEVER offers delete as substitute for stop. Stop and delete failures remain visible and preserve incident data.
- Actions trigger uses existing approved icon-button/menu composition with tools SVG, accessible label, keyboard behavior, and minimum hit target.
- Incident polling interval matches documented backend rate-limit capacity. Retry/backoff MUST NOT create request bursts.
- Tests cover authorization, identity binding, exact environment parsing for active and inactive units, fail-closed unit inspection, verified stop projection, post-lock identity, holder-bound deletion intent, service crash/retry adoption after remote absence, lease-bound expected-phase deletion transitions, explicit successor adoption, stale-holder refusal, delete absence verification, durable cleanup, globally serialized UI lifecycle actions, icon accessibility, one bounded infinite-query refresh per 15 seconds regardless loaded pages, stable timer across rerenders, proxy `Retry-After` forwarding, capped validated backoff, suspended timer/focus/reconnect during backoff, and failures.
- Collector, web, and required UI gates pass without warnings.
- Change lands on `main`, deploys, and `/incidents` receives installed owner-visible proof.

## Preserved WIP

- Worktree: `/home/user/Projects/overdeck/.worktrees/incident-actions`
- Branch: `wt/incident-actions`
- Base: current `origin/main` at worktree creation.
- Existing Incidents completion and unrelated shared-main WIP MUST remain untouched.

## Constraints

- Reuse `@platform-modules/ui-primitives` and `@overdeck/deck-ui`; NEVER create a new primitive without owner approval.
- Stop MUST use canonical incident dispatch identity and exact active service/process authority. NEVER broad-kill by model, CLI, workspace, process name, or user.
- Delete MUST enforce inactive state at backend trust boundary atomically enough to reject stale UI decisions.
- Preserve historical and resolution evidence unless owner explicitly requests broader erasure semantics; delete only canonical incident record and owned mutation state required by established storage contract.
- Follow branch → gates → guarded land → deploy. Browser/dev-server proof MUST use `e2e-remote`.

## Execution steps

1. Map existing routes, service/provider, launch authority, mutation store, query cadence, ActionsMenu/IconButton exports, and backend limits.
2. Pin stop/delete contracts and lifecycle transitions with failing tests.
3. Implement collector stop/delete operations and routes with identity/state guards.
4. Implement client/query mutations, icon Actions trigger, state-dependent menu items, visible errors, and rate-safe refresh.
5. Run focused tests, collector full suite/typecheck, deck-ui tests/typecheck, web build/typecheck, and diff checks.
6. Independently review security/correctness; repair verified findings.
7. Reconcile current `origin/main`; rerun invalidated gates; commit and guarded-land.
8. Deploy and prove installed `/incidents` behavior.

## Current receipt

2026-08-13: Current synchronized remote verification passed all code gates, but final independent review found two ship blockers. First, Kanboard can be inactive while its exact incident unit still runs, so deletion/recovery must prove the server-derived bound unit is inactive before removing or finalizing the canonical record. Second, React Query retry and the bounded poll timer can collide at a 429 backoff boundary, so one scheduler must own recovery and `AbortSignal` must reach the request. A named repair worker is active on these exact defects and regressions. Prior receipts remain evidence for the pre-repair revision only: collector 45/45, web 399/399 plus build/typecheck, deck-ui 407/407 plus typecheck, diff check clean. No local test fallback, commit, push, deploy, or shared-main mutation.

## Next executable action

Complete the active exact-unit deletion guard and single-scheduler 429 repair, rerun affected remote gates, then obtain a clean independent review before reconciling `origin/main`, committing, guarded landing, deployment, and installed proof.
