Skip to Content
GuidesTemporal Rules

Temporal Rules

Temporal rules evaluate behavioral patterns over sliding time windows of pipeline events. Where static policy checks evaluate each action in isolation, temporal rules detect patterns across many actions — a sudden spike in simulation failures, a spend velocity exceeding a threshold, or a flood of approval requests.

Setup

import { createAgent, createMemoryEventStore } from '@txfence/core' const eventStore = createMemoryEventStore({ maxWindowMs: 86_400_000, // 24 hours (default) maxEvents: 10_000, // (default) }) const agent = createAgent( config, adapters, rpcUrls, executor, undefined, undefined, undefined, undefined, // 5–8: capLockProvider, metadataVerifier, approvalProvider, receiptStore undefined, undefined, undefined, undefined, // 9–12: auditLog, telemetryProvider, capLockConfigs, policyNode undefined, undefined, // 13–14: notificationProvider, provenanceChain eventStore, // 15: eventStore 'agent-0x123', // 16: agentId — used for scoped predicates )

Policy with temporal rules

import type { Policy } from '@txfence/core' const policy: Policy = { // ...static fields... temporalRules: [ { predicate: { kind: 'simulation_failure_rate', windowMs: 3_600_000, // 1 hour threshold: 3, }, consequence: { kind: 'require_approval' }, label: 'sim-failure-guard', }, { predicate: { kind: 'spend_velocity', windowMs: 1_800_000, // 30 minutes maxAmount: 50_000n, token: 'USDC', }, consequence: { kind: 'reject' }, label: 'velocity-limit', }, ], }

Temporal rules are evaluated after static policy checks and before simulation.

Six predicate kinds

simulation_failure_rate

Triggers when simulation failure count meets threshold in window. Agent-scoped when agentId is provided.

{ kind: 'simulation_failure_rate', windowMs: 3_600_000, threshold: 3 }

contract_call_frequency

Triggers when a specific contract is called too many times in window.

{ kind: 'contract_call_frequency', windowMs: 300_000, contractAddress: '0x...', threshold: 10 }

success_drought

Triggers when success count falls below threshold in window — indicates a stalled agent.

{ kind: 'success_drought', windowMs: 3_600_000, threshold: 1 }

spend_velocity

Triggers when cumulative spend (historical + current action) exceeds limit in window.

{ kind: 'spend_velocity', windowMs: 1_800_000, maxAmount: 50_000n, token: 'USDC' }

consecutive_failures

Triggers when the last N pipeline events are all non-success, regardless of time.

{ kind: 'consecutive_failures', count: 5 }

approval_flood

Triggers when approval timeout count meets threshold in window.

{ kind: 'approval_flood', windowMs: 3_600_000, threshold: 3 }

TemporalConsequence

Three consequence kinds:

type TemporalConsequence = | { kind: 'require_approval' } | { kind: 'reject' } | { kind: 'flag_for_review' }

EventStore interface

All four methods are synchronous — no Promises. The store is meant to be hit at every pipeline event with negligible overhead.

type EventStore = { record: (event: PipelineEvent) => void query: (filter?: EventFilter) => PipelineEvent[] prune: (olderThan: number) => void // ms timestamp; events older than this are dropped recent: ( n: number, // number of events, not a window filter?: Omit<EventFilter, 'from' | 'to' | 'windowMs'>, ) => PipelineEvent[] }

EventFilter lets query() slice the window by agent, chain, outcome status, contract, or time range:

type EventFilter = { agentId?: string chain?: ChainId status?: PipelineEventOutcome['status'] contractAddress?: string from?: number // ms timestamp lower bound to?: number // ms timestamp upper bound windowMs?: number // relative window — "events in the last N ms" }

Each recorded event:

type PipelineEvent = { id: string timestamp: number agentId: string chain: ChainId action: Action outcome: PipelineEventOutcome spendAmount?: bigint }

The pipeline records events automatically after each run — recording failures are swallowed so event-store errors never crash the pipeline.

The temporal_rule_triggered rejection reason appears in audit log entries and policy evaluations when a temporal rule fires.

Last updated on