Counterfactual Navigator · Live

Not a block. A path forward.

When an agent's memory is unsafe to act on, most governance stops at “no.” POST /v1/heal/counterfactual answers a better question: what is the smallest change that would make this safe? — then applies it, re-scores, and tells you whether the target decision is now reachable.

They block. We navigate.

Traditional governance

Returns a verdict: BLOCK. The agent — or the engineer on call — is left to guess which memory caused it and what would fix it.

Counterfactual Navigator

Returns the verdict and the route out: the specific entries to refresh, the change to each, and a verified re-score confirming the action is now safe.

The current recommended_action field is negative information — “don't.” The Counterfactual Navigator adds positive information — “do this, and it becomes safe.” It turns governance from a gate into a guide.

How it works

  1. Sgraal scores your current memory state — suppose it returns BLOCK.
  2. It generates a counterfactual: the stale or low-trust entries are hypothetically refreshed (age reset, trust restored to a healthy level).
  3. It runs a verification preflight on the refreshed state and reports the decision actually achieved — so you never act on a fix that didn't work.
  4. It returns exactly which entries changed and how, in changes_applied.

Request

curl -sS https://api.sgraal.com/v1/heal/counterfactual \
  -H "Authorization: Bearer $SGRAAL_API_KEY" \
  -H "Content-Type: application/json" \
  -d @request.json

request.json — the current memory state plus the decision you want to reach:

{
  "domain": "customer_support",
  "action_type": "reversible",
  "target_decision": "USE_MEMORY",
  "memory_state": [
    { "id": "m_003", "content": "...", "type": "semantic",
      "timestamp_age_days": 41, "source_trust": 0.55,
      "source_conflict": 0.1, "downstream_count": 3 }
  ]
}

Response

The original decision was BLOCK; refreshing m_003 reaches the target. Illustrative values shown.

{
  "original_decision": "BLOCK",
  "target_decision": "USE_MEMORY",
  "achieved_decision": "USE_MEMORY",
  "changes_applied": [
    { "entry_id": "m_003", "field": "timestamp_age_days", "old_value": 41, "new_value": 0 },
    { "entry_id": "m_003", "field": "source_trust", "old_value": 0.55, "new_value": 0.85 }
  ],
  "heal_applied": true,
  "verification_omega": 22
}

achieved_decision is the result of a real verification preflight on the refreshed state — not a prediction. If the smallest refresh does not reach the target, achieved_decision reports the decision that the refresh actually produced, so you never act on an unverified fix.

The economics of the fix

Refreshing a memory entry has a real, small cost — one re-fetch or re-embedding call, typically a fraction of a cent. Acting on bad memory has a much larger expected cost: a wrong customer action, a bad trade, a compliance incident.

The Counterfactual Navigator makes that trade explicit: it shows the minimum change needed, so you refresh only what matters rather than re-validating an entire memory store. (Cost is your own re-fetch economics, not a value Sgraal returns — pair it with top_heal_roi_entry_id from /v1/insights to spend a healing budget where it buys the most risk reduction.)

What this does not replace

Human judgement on irreversible actions

A reachable USE_MEMORY means the memory state is safe to act on after the refresh — it does not authorise the action itself. For destructive or irreversible actions, keep a human approval step (/v1/approvals).

Re-fetching the data for you

The Navigator tells you which entries to refresh and verifies the outcome. Actually re-fetching the source content is your pipeline's job — Sgraal scores the refreshed state you supply.

Versioning

Last reviewed: 2026-05-24. Status: Live · doc-only (endpoint in production).

Related: /docs/insights · /docs/mvmem · /docs/api