Skip to main content
Help Center
Audit Plane 9 min read·Updated Jun 28, 2026

Reading a decision_log row — fields, evidence, and reverts

A field-by-field walkthrough of a decision_log row: what each field means, how the evidence resolves, and how a revert works.

decision_log is append-only. Every state transition an agent makes writes a row, and rows are never deleted. Each row carries the reasoning, the evidence behind it, and the cost confidence the agent had at the moment it acted. Learn to read one row and you can read the whole system.

app.magistry.io/dashboard/decisions
The Decisions page in the Magistry dashboard, with decision rows showing trigger, state transition, and evidence for each action
Every row carries its trigger, its from/to states, and the evidence frozen at decision time.

An illustrative row

decision_log rowjson
{
  "id": "a1b2c3d4-9f2e-4b7a-8c1d-6e5f4a3b2c1d",
  "store_id": "0f8e7d6c-…",
  "product_id": "5b4a3c2d-…",
  "variant_id": null,
  "from_state": "ACTIVE",
  "to_state": "OPTIMIZING",
  "trigger": "roas_below_floor",
  "evidence": {
    "action": "optimize_loser",
    "roas_30d": 0.8,
    "reasoning": "ROAS under the store floor for 30 days; rewrite before discounting."
  },
  "cost_tier_at_decision": "B",
  "applied_to_shopify": true,
  "status": "applied",
  "acted_at": "2026-06-24T06:12:40Z"
}

The fields that matter

  • evidence.action — the verb. Actions come from a fixed enum (keep, scale_winner, optimize_loser, discount_test, draft, vault, revive_seasonal, flag_orphan, wait); there is no free-form verb.
  • from_state / to_state — the lifecycle transition, which must exist in ALLOWED_TRANSITIONS or the row would be an operator-review row instead.
  • trigger — the condition that fired the planner. Machine-readable, so you can query 'everything roas_below_floor did this month'.
  • evidence — the metrics snapshot and reasoning that drove the decision, frozen at decision time.
  • cost_tier_at_decision — the cost confidence the agent actually had at decision time, not what's known now.
  • status and applied_to_shopify — whether the row is a dry-run proposal, pending, applied, skipped, or failed, and whether it actually hit Shopify.

Following the evidence

The evidence field is a snapshot, not prose alone — the metrics windows, cost data, and reasoning the agent saw, frozen at decision time. Click through in the dashboard and you see the exact numbers behind the row. This is what makes the log an argument, not an assertion: the reasoning is reconstructable from the recorded inputs.

How a revert works

There is no stored undo script. The revert executor derives the inverse from evidence.action at revert time — a draft or vault republishes the product, a discount_test restores the original price, an optimize_loser restores the previous content version — then stamps reverted_at and reverted_by on the row and rolls the lifecycle state back. The reversal is itself an auditable fact, which is exactly why finance teams trust the table.

If you can't reconstruct why an action happened from its row alone, the row is wrong. That's the standard the schema is built to.

// still stuck?

Talk to a human who knows your store.

Live chat Mon–Fri 09:00–18:00 CET, email with a 24-hour SLA, or a 30-minute call. Support reads the same decision_log you do.

Free to read · No email gate · Versioned with the platform