Skip to main content
An improvement is not a cluster — clusters are grouped failures; an improvement is a concrete fix proposal aimed at one cluster, with a title, before → after diff, and a measured delta from simulation. The loop generates and measures these; the SDK is where your product shows the queue and lets a human decide. Embedding this in your product means customers approve fixes from inside your admin surface — no jump to the Nora dashboard, but the single-approval gate is preserved (only the actor recorded in the audit changes). Authenticated by PAT read for browsing, PAT approve for decisions.

The Improvement shape

improvements.list / improvements.get return objects with:
  • id, kind, title, status
  • addresses — number of failures this improvement fixes
  • delta — simulated improvement magnitude (null when not yet measured)
  • clusterKey — the cluster this improvement targets
  • graphSlug — the Flow slug the improvement applies to (null for workspace-scoped fixes)
  • targetAgentId / targetAgentName — the agent being changed
  • diagnosis — why (from the loop’s classifier)
  • proposal — the primary before → after (mirrors changes[0])
  • changes[] — full typed change-set { surface, target, before, after, rationale }
  • compare — 2-axis simulation result (before vs after)

Browsing

Status values: proposed (waiting for a decision), approved (adopted → deployed), rejected (dismissed), reverted (a deployed fix rolled back via revert). New statuses can be introduced server-side — treat as an extensible string.

Deciding

Approve is the load-bearing verb — that’s where a human decides. Reject is advisory (proposals need approval to deploy either way). approve requires the approve scope; reject accepts read. approve({ edits }) lets you accept only some entries from the multi-surface changes[] array — e.g. take the prompt change but skip the tool config change. Indices refer to the changes array order.

Safety valves

revert is the post-deployment undo — it requires approve because it changes production. staleFixes returns fixes whose measured effect has degraded (the underlying failure pattern reappeared), so you can queue them for re-simulation.

versions

Same DAG, different level. versions deals with the Flow version pointer directly — improvements ship as versions, but you can also roll the pointer without going through the improvement queue.
Use versions.rollback when the pointer needs to move faster than an improvement revert would allow (e.g. a bad publish that had nothing to do with an improvement).

Why simulate / generate aren’t here

The improvement queue is where the loop’s output lands. Making an improvement — running the failure classifier, generating candidates, measuring them in simulation — is what the loop’s internals do, not what the SDK exposes. The SDK is the decision surface, not the generator. If you want to make evidence on-demand (e.g. re-simulate a specific fix), that’s simulations. Its promote(roundId) verb turns a simulation result into an improvement proposal that then flows back through this queue for approval.

Common patterns

Product-embedded approval

Show pending improvements in your own admin UI:
The audit records your admin user as the approver — same gate, different location.

Cherry-pick multi-surface changes

An improvement often touches several surfaces (prompt + tool policy + a data source filter). Take only the safe subset:

Watch for decay

Weekly:
Then re-simulate the fix (see Simulations) and let the loop decide whether to re-promote or leave it.