The central unsolved problem in production DeFi agents is not capability. Existing frameworks can route swaps, monitor yields, and respond to on-chain events with low latency. The problem is verifiable constraint.
What I mean here is building agents that are not merely instructed to respect user-defined boundaries, but architecturally incapable of violating them. Add an extra touch of providing tamper-proof records that prove they held the line, and that’s as close to perfection as it can get.
This distinction matters a lot as autonomous agents begin to manage real capital. An agent that “tries its best” to follow a user’s risk parameters is a liability. Meanwhile, an agent that cannot physically pass a compliance gate without a valid, active constitution entry is an entirely different class of system. The gap between these two goes down to their architectural patterns.
In building Nostra, a constitutional DeFi agent deployed on Nosana’s decentralized GPU network, I arrived at a three-layer architecture I term the Constitutional Governance Stack. Each layer addresses a distinct failure mode in autonomous agent design: (1) typed rule enforcement at the action layer, (2) state-machine execution gating, and (3) immutable on-chain audit trails. This article walks through the design, the implementation in ElizaOS v2, and the tradeoffs each layer introduces. n
The Constitutional Governance Stack

Each layer in the stack operates independently. Disabling Layer 3 does not weaken Layer 1. The stack degrades gracefully: an agent without on-chain logging is less auditable, but not less safe. This separation of concerns was done deliberately.
Layer 1: Typed Rule Enforcement
The foundation is a strongly-typed rule system that makes governing constraints simultaneously machine-readable and human-auditable.
```typescript
// src/types/constitution.ts
export interface ConstitutionRule {
id: number;
type: 'allocation_limit' | 'yield_threshold' | 'action_gate' | 'compute_budget' | 'custom';
description: string; // exact string used verbatim in on-chain memos
condition: {
metric: string; // e.g. "sol_concentration", "yield_delta"
operator: '<' | '>' | '<=' | '>=' | '==' | '!=';
value: number;
unit: string; // e.g. "percent", "apy_points"
};
action: 'block' | 'alert' | 'require_approval' | 'reduce_frequency';
}
Two design decisions here are worth examining. First, the `description` field is not a metadata label. It is the exact string broadcast to the Solana blockchain when the rule fires. This coupling means a human reading the on-chain record reads the same text the user wrote during onboarding. Everything remains unfiltered with no inference or form of translation whatsoever.
Second, the `condition` object is typed against a specific metric vocabulary, which means the compliance checker is deterministic: given the same `ConstitutionRule` and the same proposed action, the same decision is always made. There is no stochastic LLM call in the enforcement path.
The practical implication: constitution parsing uses the LLM (to convert natural-language risk preferences into structured rules during onboarding). Rule enforcement does not. This is another important piece of architectural boundary. There was a deliberate decision to place the expensive, non-deterministic component upstream of the gate, rather than inside it.
For readers building similar systems, this pattern can be generalized as:
Use LLMs for policy authoring, not for policy enforcement.
See: AI agents and deterministic vs. probabilistic decision layers
Layer 2: State-Machine Execution Gating
The compliance gate is implemented as a higher-order function (withComplianceGate) that wraps any ElizaOS Action. It applies three sequential checks, each of which can short-circuit execution:
// src/gates/with-compliance-gate.ts (abridged)
function withComplianceGateHandler(handler: ActionHandler): ActionHandler {
return async (runtime, message, state, options, callback) => {
// Check 1: Crisis state — is the agent frozen?
if (agentState.crisisStatus !== 'active') {
await sendCallback(callback, `🚨 Frozen. Crisis status: ${agentState.crisisStatus}`);
return;
}
// Check 2: Constitutional compliance — live DB read, no cache
const constitution = ConstitutionService.getActive(db);
if (constitution?.rules.length > 0) {
const result = checkConstitutionalCompliance(constitution.rules, extractProposedAction(message));
if (!result.passed) {
// Even the block is recorded on-chain
await WalletService.writeMemo(buildMemoText({
actionDescription: `NON_ACTION: ${result.violation}`,
ruleReference: `Rule #${result.ruleRef}`,
complianceStatus: 'Constitutional compliance: BLOCKED.',
}));
return;
}
}
// Check 3: Trust Ladder — has the agent earned execution authority?
if (agentState.trustLadder === 'advisor') {
await sendCallback(callback, `Advisory Mode. Accuracy: ${agentState.accuracyScore.toFixed(1)}%`);
return;
}
return handler(runtime, message, state, options, callback);
};
}
The Check 2 implementation deserves particular attention: ConstitutionService.getActive(db) performs a live database read on every invocation. This was also another very deliberate decision. If a user amends their constitution during an active session, the amendment takes effect on the next action, not the next restart.
In a financial governance system, cache invalidation is not just a performance concern, it is also a security boundary.
The Trust Ladder (Check 3) is a state machine with two states: advisor and executor. In advisor mode, the agent suggests actions but cannot execute them. Each suggestion is graded by the user. The TrustLadderEvaluator promotes the agent to executor only when it achieves ≥80% accuracy across a minimum of five graded samples:
// src/evaluators/trust-ladder-evaluator.ts
const MIN_SAMPLE_FOR_PROMOTION = 5;
if (accuracyScore >= 80 && total >= MIN_SAMPLE_FOR_PROMOTION) {
update['promotionPending'] = true; // user must explicitly confirm promotion
}
Promotion doesn’t happen automatically. Instead, the system flags a pending review that the user must explicitly confirm. This preserves human oversight as a hard requirement. [See: Human-in-the-loop design patterns for autonomous systems]
Layer 3: Immutable Audit Trails via the Solana Memo Program
The Solana Memo Program accepts arbitrary UTF-8 strings and writes them as immutable transaction data. Nostra uses this as its audit layer. Every action and every blocked action produces a memo:
// src/actions/log-decision-on-chain.ts
export function buildMemoText(params: MemoParams): string {
const timestamp = new Date().toISOString();
const suffix = ` ${params.ruleReference}. ${params.complianceStatus}`;
// Hard cap at 500 chars (Solana memo limit), truncating description if needed
const maxDescriptionLength = MEMO_MAX_CHARS - `${timestamp} — `.length - suffix.length;
const desc = params.actionDescription.length > maxDescriptionLength
? params.actionDescription.slice(0, maxDescriptionLength - 1) + '…'
: params.actionDescription;
return `${timestamp} — ${desc}${suffix}`;
}
A compliant action produces:
2026-04-12T14:32:11Z — Rotate 15% SOL → USDC via Jupiter. Rule #2. Constitutional compliance: 100%.
A blocked action produces:
2026-04-12T14:35:02Z — NON_ACTION: sol_concentration 72% exceeds max 60%. Rule #3. Constitutional compliance: BLOCKED.
The critical property of this design is how the agent records its refusals with the same permanence as its actions. A traditional logging system proves what a system did; this architecture also proves what it refused to do, and why. For DeFi agents managing user funds, the latter is arguably more important than the former.
Implementation: ElizaOS v2 as the Plugin Host
The Constitutional Governance Stack runs as a single ElizaOS v2 plugin. ElizaOS’s Provider/Action/Evaluator pattern maps cleanly to the three layers:
- Providers supply context (constitution rules, portfolio state, yield rates, trust score) to each action
- Actions are the unit of execution, wrapped with
withComplianceGatewhere they touch funds - Evaluators run post-action (grading suggestions, checking crisis triggers, updating trust scores)
The full plugin registers 18+ actions, 5 providers, and 3 evaluators. Scheduling (morning briefings, evening reports) runs via node-cron inside the container, with state persisted through a Nosana volume mount to SQLite.
Nostra was ranked sixth of 105 submissions across 32 countries in Nosana’s Fourth Builders’ Challenge, with reviewers describing it as demonstrating “a thoughtful approach to trust, compliance, and agent responsibility” [source]. That external validation, from a challenge specifically focused on production-grade GPU-deployed agents, suggests the governance gap described here is recognized as a real problem in the ecosystem.
The full implementation is open-source at github.com/Zolldyk/Nostra (branch: elizaos-challenge).
Tradeoffs and Limitations
What this architecture solves well:
- Deterministic enforcement of user-defined financial rules
- Verifiable proof of agent behavior and restraint
- Progressive trust establishment before granting execution authority
- Transparent crisis handling with structured resolution paths
What it does not solve:
- Oracle integrity. The compliance gate is only as reliable as the data it receives. If a price feed is manipulated, a rule like
sol_concentration < 60%may be evaluated against false inputs. The architecture says nothing about data trust. Anything data trust requires a separate oracle layer. - Single-node state. SQLite with a Nosana volume mount works for a single container. The Crisis Protocol freeze state needs distributed locking for multi-node deployments. In this case, a PostgreSQL migration is the correct V2 path.
- Rule completeness. A constitution with no relevant rules for a proposed action passes Gate 2 by default. The architecture enforces what is written; it cannot enforce what the user forgot to write.
Who benefits most from this approach: Developers building agents that manage user funds at any scale, protocol teams designing agent-operated treasury systems, and researchers exploring verifiable alignment mechanisms for autonomous financial systems. The Lamport Conscience pattern specifically may be valuable for any on-chain application requiring an auditable agent activity log, independent of the governance layers above it.
Conclusion
The governance deficit in autonomous DeFi agents is architectural. Instructing an agent to behave well produces a different class of system than constraining it to be incapable of behaving badly. The three-layer Constitutional Governance Stack presented here, which includes typed rule enforcement, state-machine execution gating, and immutable on-chain audit trails, provides a concrete and implementable framework for closing that gap.
The components are modular: the Lamport Conscience works without the Trust Ladder, and the compliance gate works without on-chain logging. Teams can adopt the layers independently based on their trust and accountability requirements.
The full stack, however, is the meaningful combination: an agent that cannot violate its constitution, cannot execute without earned authority, and cannot hide what it chose not to do.