# Incident Lifecycle Controls

audience: AI coding agents first.

status: BLOCKED
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: Lifecycle controls are implemented and committed in the isolated worktree. Stop and delete use server-derived exact unit identity; deletion remains inactive-only, durable, lease-fenced, and safe across remote ambiguity, task reuse, and recovery. Incident polling uses one bounded 15-second scheduler, honors validated capped `Retry-After`, disables automatic duplicate retries, and forwards cancellation to `fetch`. Post-merge remote verification passed all touched surfaces: collector lifecycle 57/57; web 43 files / 409 tests; web build and typecheck with 0 errors, warnings, or hints; `ActionsMenu` passed within deck-ui. The full deck-ui suite had one unrelated upstream `TimeSeriesChart` test failure because a new chart-axis label duplicates the expected table value; the failing assertion is unchanged on current `origin/main` and outside this feature. Independent review completed clean with no security, identity, recovery, authentication, polling, or accessibility findings. `git diff --check` passed. Upstream advanced again after verification and must be reconciled before guarded landing. No push or deploy yet.

## Next executable action

Guarded landing is blocked because the shared main checkout contains tracked edits owned by another session. Preserve them untouched. Once their owner clears or commits them, rerun guarded landing, deploy, and prove the installed stop/delete routes, tools-icon menu, and rate-safe refresh behavior.
