1. Calling an action does nothing yet
action looks like a function but behaves completely differently:
calling it only prepares — the body doesn’t run until you explicitly
commit.
"SENDING to..." line printed. mail is a prepared action object, not
a sent email.
2. .verify(), then .commit()
Two explicit steps stand between “prepared” and the real effect:.commit() — that’s the only place the real effect
happens.
3. Policy blocks it before it runs
requires email.send names the permission this action needs. policy:
grants or denies it. Deny it, and .verify() refuses before anything
happens — not a soft warning, a real error:
4. Make it undoable
An email can’t be unsent — that’s whysend_mail above is
irreversible, and Sense won’t let it declare an undo. Something that
can be undone is reversible, and must declare rollback::
a.rollback() re-checks the capability before running, same as
a.commit() does — a policy change between commit and rollback is
caught, not ignored.
reversible or irreversible?
Ask one question: does this have a real, expressible undo?
Sense enforces this at parse time in both directions — you can’t declare
reversible without rollback:, and you can’t add rollback: to
irreversible.
What you built
action— calling it only prepares; the body runs inside.commit()requires <capability>+policy: allow/deny— permission checked at.verify()and again at.commit()reversible action ... rollback: ...— a mandatory, real undo;.rollback()runs it
Next
Pausable Agents
Next tutorial — a runtime entity that waits on a human, mid-task.
Actions & Policy
The full reference — audit logs, approval gates, dry runs.
Ask a Model
Previous tutorial, if you missed it.
Which keyword do I want?
def vs tool vs action vs agent, decided in one glance.
