Every SKU lives in exactly one lifecycle state. ALLOWED_TRANSITIONS is the map of which moves between states are legal. The agent can only propose a transition that exists in the map; anything else is surfaced for a human instead of forced as a write.
The states
- draft, active, throttled, promoted — live or pre-live.
- watch — flagged for a metric breach, still live.
- winding_down, archived — phasing out / removed from sale.
- blocked — held by a policy or compliance flag.
The map
ALLOWED_TRANSITIONS = {
"active": {"throttled", "promoted", "watch", "winding_down"},
"throttled": {"active", "winding_down"},
"winding_down": {"archived", "active"},
"archived": {"active"}, # revive only via active, never direct to promoted
}Invalid moves become rows
If the agent wants archived → promoted (not in the map), it doesn't error and it doesn't mutate. It writes a review row describing the intent and the illegal transition, and asks an operator to open the transition or decline it. Those rows are where you learn your own rules are too strict.
