---
{
  "id": "platform.trigger.lifecycle-and-immutable-update",
  "topic": "trigger",
  "title": "Trigger lifecycle and immutable update",
  "locale": "en",
  "version": "2026-07-17",
  "summary": "Trigger updates atomically cancel the old row and create a new active row, so every follow-up must use the returned triggerId.",
  "content": "User-visible lifecycle distinguishes `active`, `paused`, `cancelled`, and `deleted`; `firing` is a transient conflict state. `set_enabled(false)` changes an eligible rule to paused, and `set_enabled(true)` resumes it as active. Cancelled stops future normal fires but preserves cancellation history. Deleted is a separate tombstone and is not equivalent to cancelled.\n\n`update_trigger` uses immutable append in one transaction: it cancels the old row with `system:replaced` and inserts a new active row. The response `triggerId` differs from the request ID; `replacesTriggerId` on the new row points back, and lineage can expose `replacedByTriggerId`. Always use the returned ID for follow-up operations.\n\nThe input field `enabled` remains only for backward compatibility and is ignored. A replacement always starts active; to keep it paused, call `set_enabled(newTriggerId, false)` after update succeeds. Re-cancelling an already cancelled trigger is idempotent success, but deleted rows must not be presented as successfully cancelled. Update/cancel conflicts while firing or terminal follow the shared runtime contract. Cancel and deprecated delete require confirmation; update and set-enabled do not.\n",
  "aliases": [
    "pause trigger",
    "resume trigger",
    "immutable update",
    "new triggerId",
    "replacesTriggerId",
    "system replaced"
  ],
  "tags": [
    "trigger",
    "lifecycle",
    "replacement"
  ],
  "relatedActions": [
    "arinova.trigger.get_trigger",
    "arinova.trigger.update_trigger",
    "arinova.trigger.set_enabled",
    "arinova.trigger.cancel_trigger",
    "arinova.trigger.delete_trigger"
  ],
  "relatedActionPrefixes": [],
  "url": "https://docs.arinova.ai/en/kb/trigger/lifecycle-and-immutable-update/"
}
---

User-visible lifecycle distinguishes `active`, `paused`, `cancelled`, and `deleted`; `firing` is a transient conflict state. `set_enabled(false)` changes an eligible rule to paused, and `set_enabled(true)` resumes it as active. Cancelled stops future normal fires but preserves cancellation history. Deleted is a separate tombstone and is not equivalent to cancelled.

`update_trigger` uses immutable append in one transaction: it cancels the old row with `system:replaced` and inserts a new active row. The response `triggerId` differs from the request ID; `replacesTriggerId` on the new row points back, and lineage can expose `replacedByTriggerId`. Always use the returned ID for follow-up operations.

The input field `enabled` remains only for backward compatibility and is ignored. A replacement always starts active; to keep it paused, call `set_enabled(newTriggerId, false)` after update succeeds. Re-cancelling an already cancelled trigger is idempotent success, but deleted rows must not be presented as successfully cancelled. Update/cancel conflicts while firing or terminal follow the shared runtime contract. Cancel and deprecated delete require confirmation; update and set-enabled do not.
