The decision_log is the spine under every move an agent makes. Thirty minutes here will make every other part of Magistry legible, because everything resolves to a row in this table.
The shape of a row
{
"id": "a1b2c3d4-9f2e-4b7a-8c1d-6e5f4a3b2c1d",
"store_id": "0f8e7d6c-…",
"product_id": "5b4a3c2d-…",
"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": "A",
"applied_to_shopify": true,
"status": "applied",
"acted_at": "2026-07-02T06:14:09Z"
}Integrity
The table is append-only, and rows are versioned bitemporally: system_from / system_to record when each version of a row was current, so a correction is a new version with the old one preserved — never a silent overwrite. Row-level security keeps each store's rows inside its own boundary. That's what makes the log admissible as evidence rather than just a record.
The five first-week queries
- What did the agents do today? (action counts by agent)
- What did they want to do but couldn't? (rejected rows + blocking gate)
- What did we reverse, and why?
- Which gate blocks the most decisions?
- Which evidence rows recur across decisions?
Rollback, derived from the row
There's no stored undo script. The revert executor derives the inverse from evidence.action at revert time — a draft or vault republishes, a discount_test restores the 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. Finance loves this because 'undo' is itself an auditable fact, not a deletion.
