Remediations
A remediation is a typed, tracked fix proposal for one recurring failure — drafted from the real evidence in your failing traces (system prompts, tool schemas, tool-call errors), not from generic advice. The detail reads as the fix loop it actually is: Root cause → Fix → Proof → Ship. You simulate a remediation against real failing sessions before you ship it, apply it, and then measure whether the failure actually went away.
Remediations are the action half of the Neens Fix pillar: Issues and failure modes tell you what keeps going wrong; a remediation is the concrete change that stops it.
At a glance
| Where | Fix → Remediations in the sidebar (a sortable table; click any row to open that fix’s full page), or an Issue’s Generate fix action. Every remediation has a shareable page at /remediations/{id} |
| Key API | POST /remediations/generate, GET /remediations/items, PATCH /remediations/items/{id}, POST /remediations/items/{id}/simulate, GET /remediations/items/{id}/efficacy |
| Needs | Failure evidence (a cluster or a failure mode with classified sessions). An LLM connection (Settings → Connections) for richer generation and for simulation |
| Scope | Agent-scoped — a remediation belongs to the agent whose failures it fixes |
Generate a fix
Pick a failure
Start from a failure cluster (Diagnose) or an Issue (a failure mode). Either grounds the fix in a concrete set of failing sessions.
Generate
Use Generate fix on the Issue or cluster, or call the API — at least one of clusterId /
failureModeId is required (the request is rejected with 422 otherwise):
curl -X POST "https://<your-neens-host>/remediations/generate" \
-H "Authorization: Bearer $NEENS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"failureModeId": "fm-abc123"}'Review the draft
The new remediation lands in Fix → Remediations with status Proposed, a typed artifact (the actual before/after change, with a diff you can open and copy — see The Fix stage), an inline proof eval, and a priority score.
How generation works
Neens reads the failure’s real trace evidence — captured system prompts, tool schemas, tool-call arguments and errors, HTTP status codes, span kinds and statuses, model parameters, and representative failing input/output examples — then:
- Derives the root cause from the evidence, not the label. Neens reads the dominant error signature across the failing sessions — the HTTP status codes in the errors, the error class names, the span kinds and their pass/fail status — and writes a likely cause grounded in what it found, e.g. “≈94% of sampled sessions fail with HTTP 503 ‘connection pool exhausted’ from the ticket service.” The likely cause is never a restatement of the cluster label.
- Classifies where the failure lives — its failure locus: is it your agent’s reasoning, a tool contract, a downstream or upstream service, a genuine quality problem, or a control working exactly as intended? This is decided from the evidence (status codes, error classes, guardrail messages), so a real 503 becomes an infra advisory and a correctly-firing refund limit becomes working-as-intended — organically, not from a keyword in the label.
- Routes to a locus-appropriate fix type (see Remediation types) and
drafts a grounded artifact with the agent’s LLM connection: for an agent-fixable failure the
artifact’s
beforequotes the real captured text (the actual system prompt, tool schema, or error) andafteris the proposed replacement, with a unified line diff. For a service failure the artifact is an advisory that names the owning component and the recommended resilience fix instead of a prompt edit. - Self-critiques the draft in a second LLM pass — checking that
beforeis a genuine quote, that the proof eval is specific enough to catch this exact failure, and that the fix type and target are consistent — and keeps the improved version. - Attaches a proof eval — an LLM rubric defining what “fixed” means for this failure. It is reused as the default judge when you simulate.
- Applies the grounding gate — a proposal with no concrete change (or too little evidence to classify) is held as needs grounding and kept out of the actionable backlog.
- Computes a priority (see below), ranked by fixability — an advisory or a working-as-intended item ranks below a genuinely agent-fixable change.
No LLM connection? Generation still works. Without a resolvable connection (or if the LLM call fails), Neens falls back to a deterministic draft derived from the failure locus and the captured evidence — the locus, likely cause, owning component, and advisory recommendations are computed from the evidence without an LLM, so an infra advisory or a working-as-intended verdict is still correct. What the deterministic path can’t do is write a specific prompt rewrite: if it can only produce boilerplate (“clarify the agent’s instructions…”) for an agent-fixable failure, that proposal is held as needs grounding rather than shown as an actionable fix. Configure a connection to get fixes that quote and rewrite your actual prompts.
Sharpen your fixes with Agent context. The Agent context drawer on the Remediations page
lets you paste your agent’s canonical system prompt, repo URL, and intended-behavior notes
(PUT /remediations/agent-context). Neens folds this into future generated fixes so they get
more specific to your agent. All fields are optional.
Where the failure lives (the failure locus)
Before it proposes anything, Neens decides where the failure actually lives — because the honest fix for “your agent chose the wrong tool” is nothing like the honest fix for “the ticket service was down.” That classification is the failure locus, and it’s read from the evidence, not the cluster label:
| Failure locus | What the evidence shows | This is… |
|---|---|---|
| Agent reasoning | A bad plan, wrong tool choice, hallucination, or an ignored instruction | Your agent — fixable in your repo |
| Tool contract | Malformed arguments, a schema mismatch, a 400/422 from bad input | Your agent’s call — fixable in your repo |
| Downstream unavailable | A tool’s own backend returns 5xx/503/504, times out, or reports a pool exhausted / maintenance | A service, not your agent |
| Upstream unavailable | The tool succeeded but a service it called returned 5xx/timeout (named in the error) | A dependency, not your agent |
| Guardrail (correct) | A guardrail or business rule fired correctly — the request genuinely violated a rule | A control working as intended |
| Quality | A low judge score (relevancy / faithfulness) with no infra error present | Your agent — fixable in your repo |
| Incoherent | The grouped sessions are heterogeneous — different tools, different errors, or no error at all | Not one failure — needs re-clustering |
| Unknown | Not enough evidence to classify | Undetermined |
From the locus, Neens sets an actionability — how you’re meant to act on the fix — and it drives both the backlog and the sort order:
| Actionability | Which loci | What it means for you |
|---|---|---|
| Actionable | agent reasoning, tool contract, quality | Your agent team can fix it in-repo. Shown in the backlog by default. |
| Advisory | downstream / upstream unavailable | Not agent-fixable — route it to the service or infra owner. Hidden from the actionable backlog unless you ask for advisories. |
| Non-actionable | guardrail (correct), incoherent, unknown | Nothing to ship — a control worked, or there isn’t a single fixable cause yet. Hidden from the actionable backlog. |
The whole point is to stop proposing prompt edits for things a prompt can’t fix. If your agent
is getting 503s from a ticket service, no rewording of its system prompt makes the service come
back. Neens says so plainly, names the owner, and recommends the resilience change that would
help — see the advisory examples below.
Remediation types
Every remediation carries a type — what kind of change the fix is — so it can carry a concrete artifact (or a concrete recommendation) rather than free-text advice. The agent-fixable types stay as before; the grounded flow adds four types for the service and control-plane loci:
| Type | The remediation is… | Typical locus |
|---|---|---|
prompt_change | A change to the system prompt | agent reasoning |
tool_schema | A change to a tool’s description or argument schema | tool contract |
param_change | A change to a model parameter (e.g. temperature) | tool contract |
guardrail | A change to an input/output guardrail rule | agent reasoning |
retrieval | A change to retrieval / context-assembly configuration | agent reasoning |
routing | A change to routing / escalation rules (e.g. hand off to a human) | agent reasoning |
add_eval | Encoding the failure as a permanent regression eval | quality |
kb_fix | A fix to stale knowledge-base content | agent reasoning |
infra_advisory | New. An advisory that a service is failing — names the owning component and the recommended fix; not an agent edit | downstream / upstream unavailable |
tool_resilience | New. A resilience change to how your agent calls a flaky tool — bounded backoff with jitter, a circuit breaker, an idempotency key, or a queue | downstream unavailable |
escalate_to_owner | New. Route to a named external owner when your agent has no viable mitigation and the fault is clearly someone else’s service | downstream / upstream unavailable |
working_as_intended | New. No action — a guardrail or business rule fired correctly | guardrail (correct) |
Worked examples
Your create_ticket tool starts returning HTTP 503 “connection pool exhausted” across a burst
of sessions. The failing span is the tool’s own call, so the locus is downstream unavailable and
the actionability is advisory.
Neens does not propose a prompt edit. It generates an infra_advisory:
This is a downstream service failure, not an agent defect. Owner: ticket-service. ≈94% of sampled sessions fail with
HTTP 503 "connection pool exhausted". The agent already retries once with no backoff. Recommended: bounded exponential backoff with jitter, a circuit breaker so the agent degrades gracefully during an outage, and an idempotency key so a retried ticket isn’t created twice.
The resilience half of that recommendation is exactly a tool_resilience change — something
your agent code can own even though the outage isn’t your fault.
Failure categories
Alongside the locus, Neens keeps a finer-grained failure category for the agent-fixable loci; a known category can refine the default fix type and the shape of the generated artifact:
| Category | Typical signal | Default fix type |
|---|---|---|
malformed_output | Invalid JSON, schema violations, parse errors | tool_schema |
wrong_tool | The agent called an inappropriate or unknown tool | tool_schema |
missing_context | Retrieval/truncation left out the needed evidence | retrieval |
loop_nontermination | The agent spun on the same step, never stopped | param_change |
over_refusal | Benign, in-policy requests were refused | prompt_change |
hallucination | Ungrounded or invented claims | prompt_change |
planning | Skipped or reordered required steps | prompt_change |
multi_agent | Dropped context or misrouted hand-offs between agents | routing |
other | Nothing else matched | prompt_change |
Priority
Every remediation carries a RICE-style priority score (0–100) so you can work the highest-leverage fixes first. In the detail it folds into a single priority chip (its band); the full breakdown lives in the chip’s tooltip. It combines:
| Factor | Meaning |
|---|---|
| Reach | How many sessions the failure affects (log-damped, so a giant cluster doesn’t drown everything else) |
| Impact | How bad the failure is (per-category default, 0–1) |
| Confidence | How sure we are the fix works — starts low (0.3 unsimulated) and is earned by simulation |
| Effort | How much work the change is (per-type default; higher effort lowers priority) |
| Fixability | How much you can actually do about it. An actionable, agent-fixable failure counts full; an advisory (someone else’s service) and a needs-grounding item are damped down; a working-as-intended item is zero — a working control is never “high priority to fix” |
The score is bucketed into a band: critical (≥ 60), high (≥ 35), medium (≥ 15), else low. Sort the table by Priority (or newest-first), and filter by work state, status, type, or label. Because fixability is a factor, a genuinely fixable prompt change out-ranks a higher-volume infra advisory — the backlog is sorted by what you can fix, not just by how loud a failure is.
Needs grounding: held out of the backlog
A remediation is only useful if it carries a concrete change. Neens will not put a fix in your actionable backlog just because it exists — an empty or templated proposal is worse than none, because it looks like work that isn’t there. A proposal is held as needs grounding (and kept out of the actionable/open backlog) when any of the following is true:
- it’s an agent-fixable type but the artifact has no concrete change —
beforeequalsafter, or the change is the generic filler “clarify the agent’s instructions…” that the deterministic fallback emits when it has nothing specific to say; - there’s no usable error signature and no confidence to stand on;
- the locus is incoherent (the grouped sessions aren’t one failure) or unknown (not enough evidence to classify) — here the honest next step is to re-cluster or gather more evidence, not to ship a guess.
A needs-grounding item isn’t deleted — it’s parked. In the UI it lives in a distinct Needs grounding section, separate from the actionable backlog, so a real fix is never buried under placeholders.
Surfacing held items anyway. The list and the MCP list_open_remediations tool
default to showing only grounded, actionable items. To see what’s being held, add
include_ungrounded=true (needs-grounding items) or include_advisories=true (service advisories)
to GET /remediations/items, or use the corresponding view filter in the UI. You can also filter
directly by actionability= (actionable / advisory / non_actionable) or failure_locus=.
Advisories are complete, just not agent-fixable. An infra_advisory or a working_as_intended
item that names its cause and owner is grounded — it’s a finished, honest answer. It’s excluded
from the actionable backlog because there’s nothing for your agent team to ship, not because it’s
unfinished. Ask for advisories explicitly (above) to work them with the right owner.
One root cause, one remediation (deduplication)
The same underlying failure often fragments across several agents or clusters — three different
agents all timing out against the same ticket service look like three problems but are one. Neens
collapses them: each remediation carries a root-cause signature (a normalized
locus:component:error key, e.g. downstream_unavailable:ticket_service:503_pool_exhausted), and
when a new proposal matches the signature of an open remediation already in the agent, Neens
merges it instead of inserting a duplicate — it adds the new cluster’s reach to the existing row,
records the additional affected agent/cluster in the evidence, and recomputes priority against the
combined impact.
The result is one remediation that says “this affects N agents” with the total reach behind it — so a widespread root cause rises in the backlog on its true blast radius, and you fix it once rather than triaging the same thing three times.
Applying a fix requires a bound proof
You can’t move an actionable remediation to applied or verified on a hunch. Neens requires a bound proof first — evidence that the fix actually works:
- a completed verification run (the
pass^kresult from an eval-verified PR) bound to the remediation, or - a proof-eval gate — the failure mode’s dataset + judge (an eval gate) — that a fix can be run against.
Without one, the transition is refused with a clear message telling you what’s missing (an HTTP
409, mirrored in the UI as a disabled Apply / Verify control with an explanatory tooltip) —
never a silent success and never a crash. The fastest way to bind a proof is to
simulate the fix and then let the eval-verified PR flow open a
verified pull request; both leave a bound proof on the remediation.
Overriding the gate. If you’ve verified a fix by other means, you can still record it as applied
by confirming an override and recording a reason (the API accepts ?force=true with a reason;
the reason is stored on the remediation). Use it deliberately — the whole point of the gate is that
“we shipped it” and “we proved it” stop being the same claim.
Advisories settle differently. An infra_advisory, escalate_to_owner, or
working_as_intended item can’t be proven by an agent eval — there’s no agent change to test. These
close with an acknowledgement note (who’s handling it, what was done) and settle as closed
with an outcome note rather than verified.
The remediation detail: the fix loop
Click any row in the list to open that remediation’s own page, /remediations/{id} — and the
detail is laid out as the four-stage loop the fix moves through:
Root cause → Fix → Proof → Ship. A persistent header sits on top; the four stages sit below it.
Each stage toggles independently (it’s not an accordion), so you can have several open at once. The live stage opens by default and a completed stage collapses to a one-line receipt. Use Expand all / Collapse all (just above the stages) to open or fold every section — including the trailing Affected sessions disclosure — in one click.
The header (always visible)
The header never collapses, so the three things you most need are on screen no matter which stages you have open:
- Title and a one-line root cause — what’s being fixed, in a sentence.
- A proof-state pill (the proof status) and a work-state chip (your team’s triage lane) — the two independent tracks, side by side.
- Four stat tiles — Sessions (how many failing sessions ground the fix), Confidence
(earned by simulation), Sim Δ (the before→after pass-rate lift from the latest conclusive
simulation), and Efficacy (the post-deploy verdict). A tile with nothing to report yet reads
as a muted ”—” — never
0, never a green number (see Reading “unknown” honestly). - One primary action — the single most useful next step (below), a View diff button (shown unless View diff is already the primary action, so it never appears twice), and an overflow ⋯ menu (move to another work state, archive/unarchive, delete).
The primary action is whatever the loop is waiting on:
| Where the fix is | Primary action |
|---|---|
proposed | Accept |
accepted, not yet simulated (or the last sim failed) | Simulate fix |
accepted, simulation passed, fix engine available | Auto-fix (eval-verified PR) |
| A pull request is open | View PR |
applied, efficacy not yet measured | Record merge |
| Anything else | View diff |
While a simulation or a fix run is actually in progress, the header shows that it’s running rather than offering an action to start another.
Root cause
The first stage is always complete — it’s why the remediation exists. It shows the failure
summary, the evidence-derived likely cause (the dominant error signature across the failing
sessions, e.g. “≈94% fail with HTTP 503 ‘connection pool exhausted’ from the ticket service” —
not a restatement of the cluster label), a failure-locus badge and an actionability badge
(see Where the failure lives), a failure-category
chip, and the evidence it’s grounded in (the failing sessions and cluster it was drafted from).
For an advisory, this stage also names the owning component — the service responsible — so you
can route it. Once you’ve read it, collapse it to its one-line receipt: e.g. “Grounded in 14
hallucination sessions.” An ungrounded receipt (a fix with no attached failing sessions) is
itself a signal — the fix is advice, not evidence, until it’s linked to a failure.
Fix
This stage holds the grounded fix artifact: the target (what to change), the change
instruction and rationale, and the concrete change itself. For a prompt_change you see the
prompt before → after; for other types you see the raw unified diff — one representation,
never both.
View the full diff
Click View diff in the header. A Fix diff dialog shows the whole unified
diff — added lines in green with a leading +, removed lines in red with a leading - — with the
line count and size in the footer.
Copy it
Click Copy to clipboard in the dialog. It confirms with Copied to clipboard. If your browser blocks clipboard access you’ll see Couldn’t copy automatically — select the text and copy it manually — select the diff text in the dialog and copy it with your keyboard.
Apply it in your codebase
Paste the diff into your editor or coding agent and make the change. Applying it by hand is one of three routes: the highlighted View fix bundle card in the Fix stage gives your coding agent a complete pack — root cause, the fix, anonymized failing examples, and the proof-eval gate command — see Fix bundles; and, where it is enabled, the eval-verified fix opens a proven PR against your repo for you to review and merge.
When the fix engine is enabled for your agent, its controls live in this stage too — launch an eval-verified PR, and the stage’s receipt reflects the result (“PR opened, fixes 12 of 14 evals”, a draft that needs a human, or a failed run to read).
The highlighted View fix bundle card opens the coding-agent-ready pack — root cause, grounded fix, proof evals — in a dialog with a one-click Copy to clipboard. See Fix bundles.
Proof
Before shipping, simulate the fix: Neens replays it against a sample of the real failing sessions and shows a before → after pass-rate comparison, so you apply fixes that actually help and skip the ones that don’t. This stage shows the proof-eval rubric, the simulation plan, and the results; its Configure controls open in a slide-over drawer so the stage stays readable.
Use Simulate fix (POST /remediations/items/{id}/simulate). On production deployments the
simulation runs in the background on a worker — the stage shows a pending banner and polls for
the result, so you can keep working. Simulation requires an LLM connection; without one the request
is rejected with a clear 400 rather than failing mid-run.
Editable criteria
Open the Configure drawer to steer exactly how the simulation runs; a live plan preview shows what would run before you commit:
| Criterion | Behavior | Default |
|---|---|---|
| Judge | Which evaluator decides pass/fail | The failure mode’s judge, else the fix’s own proof eval, else a generic correctness judge |
| Threshold | Pass mark: pass = score ≥ threshold | The judge’s threshold (0.5 for the built-in fallbacks) |
| Model | Which LLM connection runs the replay and the judging | The agent’s default connection |
| Max traces | How many sessions to replay | 6 (cap 20) |
| Sampling | first or most recent failing sessions | first |
| Cohort | Tick exact sessions from a per-trace list; only genuine members of the failure’s cluster are accepted | Auto-sampled |
| Strategy | auto, rewrite, or replay (see below) | auto |
The resolved choices — including the exact session ids — are pinned to the run, so the background worker replays exactly the cohort you previewed even if new failures arrive in between.
Two strategies
| Strategy | What it does |
|---|---|
| Answer-rewrite | For each failing session, asks the model to produce the output the agent would return with the fix in place (given the original request and any retrieved context), then re-judges that corrected output. Works for any fix type. |
| Record-and-replay | Actually re-runs the agent’s turn with the fixed system prompt installed, letting the model drive tool calls — and serving each requested tool’s result from what was recorded in the original trace. Nothing touches production systems. Higher fidelity: a prompt fix that changes which tools the agent calls is exercised for real, not paraphrased. |
Auto picks record-and-replay when the fix is a system-prompt change and the model connection supports tool calling; otherwise it falls back to answer-rewrite. If record-and-replay turns out to be impossible at run time (e.g. the model rejects tool calling), the run degrades to answer-rewrite automatically and the result says so. The results always show which strategy actually ran.
The rewrite model is deliberately never shown the judge’s rubric — the judge grades the fixed output independently. Otherwise the simulation would degenerate into “write something that passes” and every fix would look perfect.
Reading the results
Results show pass-rate before and after, plus a per-trace breakdown: which traces the fix fixed, which it broke, and which were unchanged. A delta-keyed next step appears — if the fix improved things you get an Apply call to action; if it’s flat or regressed you’re prompted to adjust the criteria (with a warning when any trace got worse). When it’s done, the stage collapses to a one-line receipt — e.g. “Passed: 21% → 76%.”
Honest inconclusives. Not every result can be trusted, and Neens says so instead of claiming a lift:
- Inconclusive — the fixed output couldn’t be synthesized for a trace (or its re-score was unparseable). Its “after” score is pinned to the unchanged baseline — never a guessed improvement — and the result reports how many traces could actually be simulated. The stage receipt reads Inconclusive, not a pass-rate.
- Diverged (record-and-replay only) — the fixed prompt drove the agent to a tool call that was never recorded in the original trace. The trajectory has genuinely left the captured run, so Neens stops that trace and reports it honestly rather than fabricating a tool result. Diverged traces are also pinned to their baseline.
Treat an inconclusive or heavily-diverged simulation as “needs more evidence,” not as a pass.
A completed simulation updates the remediation’s confidence — it is earned from the replay: the after pass-rate dominates (weight 0.6), blended with the before→after improvement (weight 0.25). The basis is stored with the fix so you can see where the number came from.
Apply changes the lifecycle, not your agent. The Apply action marks the remediation
applied so Neens starts tracking efficacy — it does not modify your agent. Ship the change
yourself (View diff → Copy to clipboard, or a fix bundle /
eval-verified PR), then record a deploy event so the change is
correlated with the outcome — see What changed. Note that Apply is only
available once a proof is bound to the fix — see
Applying a fix requires a bound proof.
Ship
The last stage answers did shipping it actually work? — one “After merge” card that folds together the deploy/proof status, the PR / commit / verification links, and the efficacy verdict.
Once a fix is applied, Neens measures whether the failure actually shrank in live traffic.
GET /remediations/items/{id}/efficacy compares:
- Baseline volume — how many sessions the failure’s cluster had when the fix was proposed (snapshotted at generation time), against
- Current volume — how many sessions that cluster has now,
and returns the reduction, the reduction percentage, and a verdict: improved (volume fell), flat (no change), regressed (volume grew), or unknown (not enough data to compare). The card sits next to the What changed list of deploy events recorded in the 7 days before the fix was proposed, so you can correlate the failure (and the fix) with real changes — see What changed.
Use the verdict to move the proof status forward: mark the fix verified when the volume drop
holds, or regressed if the failure returns. To make sure it stays fixed, turn the failure mode
into a standing eval gate.
Reading “unknown” honestly
Everywhere in the detail, a value that hasn’t been earned yet is shown as exactly that — and never dressed up as a success:
- A stat tile with no result reads a muted ”—”, not
0. - The Proof stage reads Not run until you simulate, and Inconclusive when the replay couldn’t be trusted — neither is a pass.
- The Ship stage reads unknown when there isn’t enough post-deploy data to compare — not “no improvement.”
Each of these is a receipt of what hasn’t happened yet, so you can tell “this fix is proven”
apart from “we haven’t checked.” An unknown is never a green tick and never a zero — it’s your
cue to run the next step (simulate, apply, or wait for more traffic).
Affected sessions
At the bottom of the detail, an Affected sessions disclosure shows the count of failing sessions grounding the remediation. Expand it to browse the actual sessions; it loads only when you open it, so a remediation with a large cluster stays fast to view.
Triage: status vs. work state
Each remediation has two independent tracks — keep them straight, they answer different questions.
Proof status — is this fix proven and shipped?
| Status | Meaning |
|---|---|
proposed | Drafted from evidence; not yet reviewed |
accepted | Reviewed and agreed it’s the right fix |
applied | The change has been shipped to your agent |
verified | Post-deploy data confirms the failure is actually reduced |
closed | Done and put to rest |
regressed | A previously-fixed failure has come back |
Work state — where is this in my team’s queue? A simple triage lane, orthogonal to proof status:
| Work state | Meaning |
|---|---|
todo | Not started (the default) |
in_progress | Someone is on it |
done | Worked through |
archived | Soft-hidden (reversible; shown again with Include archived) |
A fix can be applied (proof) while still in_progress (work), or proposed while parked in
todo. Both are updated with PATCH /remediations/items/{id} (status, workState, labels) —
in the UI, from the header’s overflow ⋯ menu — and an unknown value is rejected with 422.
Delete is a permanent hard-delete that also removes the fix’s simulation history.
Moving a remediation to accepted is normally a human decision, and by default it stays one. An
agent can hand part of that over with an autonomy level; a human still merges
every resulting PR.
The Remediations list
Fix → Remediations is a dense, sortable table — one row per remediation — so you can scan and triage many fixes at once:
| Column | |
|---|---|
| Title | What’s being fixed |
| Type | The remediation type |
| Priority | The priority band chip |
| Status | Proof status |
| Work state | Your team’s triage lane |
| Confidence | Earned by simulation (a muted ”—” until it is) |
| Sessions | How many failing sessions ground it |
| Updated | Last change |
Click a sortable column header (every column except Work state) to sort by it. Search and the filters (sort, work state, status, type, label, and Include archived) sit right beside the rows, and label chips filter with one click.
By default the table shows the actionable backlog — grounded, agent-fixable fixes. Service
Advisories and Needs grounding items live in their own views so they don’t crowd the work
you can actually ship; switch to them (or add include_advisories=true / include_ungrounded=true
to the API call) when you want to route advisories to a service owner or review what’s being held.
You can also filter by actionability and failure locus directly.
Open a remediation. Click any row to go straight to that remediation’s full page — the
fix-loop detail at its own shareable URL,
/remediations/{id}, the link to paste into a ticket or hand to a teammate. A thin coloured rail on
the left of each row marks its proof status and the Confidence column shows a small meter, so
the table scans at a glance.
- Press J / K to move the highlighted row down / up without reaching for the mouse.
- Press Enter to open the highlighted remediation.
Overview. The failure-volume trend and the summary stats are tucked into a collapsed Overview disclosure at the top, so the table and filters get the space by default. Expand it when you want the fleet-level picture; it remembers your choice.
A deep link from a failure mode (?failure_mode_id=…) opens the list already filtered to that
failure’s remediations, with a banner telling you so. Clear the banner to see everything again.
API reference
| Endpoint | Purpose |
|---|---|
POST /remediations/generate | Draft a fix from clusterId or failureModeId (422 when neither is given) |
GET /remediations/items | List; filters clusterId, failureModeId, status, workState, type, label, q, sort=priority, includeArchived, actionability, failure_locus, include_advisories, include_ungrounded (default: grounded + actionable only) |
GET /remediations/items/{id} | Full detail incl. simulation history and correlated deploy events |
PATCH /remediations/items/{id} | Update status, workState, labels; moving to applied/verified requires a bound proof (or ?force=true with a reason) |
DELETE /remediations/items/{id} | Permanent hard-delete (incl. simulation history) |
GET /remediations/items/{id}/simulation-plan | Preview what a simulation would run (no LLM calls) |
POST /remediations/items/{id}/simulate | Run the counterfactual simulation (background on production deployments) |
GET /remediations/items/{id}/efficacy | Baseline-vs-current failure volume verdict |
GET /remediations/stats | Counts by status/work state/category — plus by failureLocus, actionability, and groundingStatus — with average confidence and priority |
GET /remediations/agent-context / PUT /remediations/agent-context | Read / set the agent context (one per agent) |
Related
- Issues and failure modes — where the failures come from
- Fix bundles — export a remediation as a coding-agent-ready pack
- Eval-verified PR — let Neens open a proven PR for the fix
- Eval gates — keep a fixed failure from silently coming back
- What changed — correlate regressions with deploys
- Judges — the evaluators simulations use to score before/after
- Insights — regression and anomaly detection across your fleet