BotanaryBotanary
Rules

Constraint types

The real constraint types AgentGuard, Smart Sessions, and mandates enforce - what each binds and how it's set.

Botanary has three separate places authority gets bound, each with its own constraint vocabulary. This page is the reference for all three: your account's own rules (AgentGuard), a v1 delegation's policy (Smart Sessions), and a mandate's policy (the mandate executor).

Account rules (AgentGuard)

These are the constraint types available on your own account, set through AgentGuard's owner-lane setters.

ConstraintBindsSet with
Frozenthe whole accountsetFrozen(bool)
Spending capa token, over a rolling periodsetCap(token, limit, periodSeconds)
Per-action maxa token, on a single actionsetPerActionMax(token, max)
Allowed contractsa contract addressaddAllowedContract / removeAllowedContract
Denied contractsa contract addressaddDeniedContract / removeDeniedContract
Recipientsa payee addressaddRecipient / removeRecipient
Permitted stablecoinsa tokenaddPermittedStablecoin / removePermittedStablecoin
Safe harbora recovery addressaddSafeHarbor / removeSafeHarbor

A denied contract or recipient always wins over an allowed one. An empty allow or deny list is unrestricted, not locked down - you tighten these over time, starting from open. A safe-harbor address stays reachable even while the account is frozen, so freezing never traps your own recovery path.

Spending caps run over one of three fixed periods:

PeriodLength
day24 hours
week7 days
month30 days

Unlike a delegation's spend meter, an account cap resets at the end of its period rather than just expiring - each cap tracks its own limit, what's been spent, what's remaining, and when it next resets.

A v1 delegation's policy (Smart Sessions)

A delegation's bounds are checked in ERC-4337 validation, before the operation is ever included on-chain:

ConstraintBindsNotes
budgetstotal spend per tokenlifetime cumulative, never a rate
perActionMaxmax per single actionoptional
maxActionstotal number of actionslifetime count, never a rate
recipientAllowlistwhich addresses can receive fundsempty means unbounded
allowedActionswhich (contract, function) pairs are callableeach needs at least one function selector
expiresAtwhen the whole grant lapses

See Granting a delegation for how each of these gets set and what their real limits are (like the 16-recipient ceiling).

A mandate's policy (the mandate executor)

A mandate binds a different, fail-closed vocabulary, checked in execution rather than validation:

ConstraintBindsNotes
Venueswhich (contract, function) pairs are callableempty denies every call
Argument rulesa max value or a required exact value, at a specific argument positione.g. capping a job's budget, or pinning a provider address
Recipientswhich addresses can receive fundsempty denies every payee
Per-venue maxa spend cap on a specific venueunset is read as refuse, not unlimited

Where a v1 delegation's empty allowlist means "allow all," a mandate's empty venue or recipient list means "deny all" - the two shapes fail in opposite directions on purpose. See Granting a delegation for how a mandate gets built.

Three enforcement points, three vocabularies: AgentGuard binds your own actions, Smart Sessions binds a v1 delegation, and the mandate executor binds a mandate. A rule set in one place has no effect in another.

On this page