All views expressed here are my own and do not represent the views of my employer.

Over the last several articles, I've been building an argument: that the orchestrator model for multi-agent systems is hitting its ceiling, that adversarial specialization produces better collective decisions than consensus-seeking, that agent trust should be earned through demonstrated performance, and that the industry needs an open consensus protocol for how agents reach agreement.

But I've also been building something else - a personal trading application that applies all of these principles to real financial markets. Not as a product. As a way to pressure-test whether these architectural ideas actually hold up when you implement them against live market data.

This page is an interactive walkthrough of the architecture behind that system. Seven layers, from the event substrate at the bottom to the observability layer at the top. Click each layer to explore how it works, why I made the design decisions I did, and what it looks like in the context of trading. Think of it as the blueprint behind the articles.

The Stack

Click any layer to explore. Read bottom-up for the foundation story, or top-down for the value story.

07 Observability & Audit Every decision traceable. Every transition recorded.

If you can't explain how a decision was made, you can't trust the system that made it. This is especially true in trading, where every action has financial consequences and regulatory implications.

The observability layer provides three capabilities: causal tracing (given any decision, reconstruct the complete chain of events and reasoning that produced it), performance monitoring (real-time KPIs for every agent - decision accuracy, confidence calibration, response latency, budget consumption), and immutable audit (a tamper-evident log of every security-relevant action).

Causal event DAG

Every event in the system carries a caused_by field - a list of parent event IDs that triggered it. This creates a directed acyclic graph of causality. When the portfolio agent executes a trade, you can trace backwards through the DAG: trade was caused by a consensus decision, which was caused by three agent votes, which were caused by market data events, which were caused by an earnings release. The full reasoning chain is reconstructable, not just logged.

Hash-chained audit

Every trust change, autonomy transition, guardrail violation, and operator action writes to an append-only log where each entry is hash-chained to the prior entry. If anyone modifies a historical record, the chain breaks and integrity verification catches it. This isn't just compliance theater - it's the mechanism that makes earned autonomy trustworthy.

In the trading agent

When a position is taken, the audit trail shows: which market event triggered analysis, what each scorer produced, how the synthesizer weighted the views, what the consensus outcome was, whether the risk agent approved, and what the portfolio agent executed. A human reviewer can replay the entire decision in under 60 seconds.

Causal attribution engine

Beyond tracing decisions, a causal attribution engine builds a Bayesian graph from trade outcomes - attributing results to the specific signals that influenced them. Over time, this graph reveals which signal types actually predict outcomes versus which ones are noise. A simulation runner uses this graph for Monte Carlo forward projections, scoring candidate actions before execution. The system doesn't just record what happened - it learns why.

Strategy evolution

The system runs continuous A/B experiments across strategy variants. A strategy tracker records which variant was active at each trade. An evolution engine compares variants and promotes winners after statistical significance gates are met - not just after a few good trades. This is self-improvement as a runtime property: the system evolves its own playbooks based on evidence, with human approval required for any strategy promotion that changes the system's behavior in production.

Right-to-erasure with immutable audit

Here's a hard compliance problem: regulations like GDPR require data erasure, but audit logs must be immutable. The solution is crypto-shredding - audit entries are encrypted with per-subject keys. Destroying a subject's key renders their entries unreadable while preserving the hash chain's integrity. A drain pipeline writes entries to external immutable storage for regulator-grade retention. The system reconciles two seemingly contradictory requirements.

Why not just use standard logging?

Logs tell you what happened. The causal DAG tells you why. In a multi-agent system where decisions emerge from the interaction of many agents, "what happened" is insufficient. You need to trace causality across agent boundaries - and standard logging frameworks don't capture multi-parent causal relationships.

06 Earned Autonomy Trust is demonstrated, not assumed.

Every agent in the system operates at a specific autonomy level that governs what actions it's permitted to take. The levels aren't about capability - they're about demonstrated trustworthiness. An agent might be technically capable of full autonomy on day one, but it starts at the bottom and earns its way up.

L4 Fully autonomous Creates own strategies. Requires 95% composite KPI + human approval.
L3 Novel with oversight Proposes actions beyond guardrails. Human approves before execution. 85% KPI.
L2 Autonomous within guardrails Novel decisions within hard boundaries. Like a trader with a risk limit. 75% KPI.
L1 Strategy selection Chooses among predefined playbooks. The playbooks are human-designed. 70% KPI.
L0 Deterministic only Follows explicit rules. No discretion. Where every agent starts.

Seven-gate validation

Every agent decision is wrapped as an immutable "intent" before it becomes an action. That intent passes through a uniform validation pipeline with seven gates: autonomy-tier compatibility (is this agent allowed to do this?), confidence threshold (is the agent confident enough?), kind registration (is this outcome type recognized?), handler pre-flight (is the execution path valid?), budget check (can the agent afford this action?), idempotency verification (has this exact action already been taken?), and multi-step transaction validity (does this fit the current saga state?). Governance is a property of the runtime, not a discipline teams follow voluntarily.

Scoped procedural memory

Agents accumulate learned policies over time - but those policies need to be scoped. An agent can hold private skills (its own specialized knowledge), a workspace can hold shared playbooks (team-level coordination rules), and the platform can hold global policies (organization-wide constraints). The scoping is explicit with defined cascade rules - a global policy overrides a workspace playbook, which overrides an agent's private skill. This prevents contamination between specialized agents while allowing shared knowledge where it belongs.

Declarative policy engine

Alongside the imperative runtime guardrails, a declarative policy engine lets compliance teams author governance rules without code changes. Think Rego-style policy-as-code. The separation matters operationally: policy authorship belongs to compliance; code changes belong to engineering. The platform enforces both, but they evolve on different cadences and are owned by different teams.

The asymmetry principle

Promotion is slow - sustained performance across decision accuracy, confidence calibration, guardrail compliance, budget efficiency, and response rate. Must hold threshold for a configurable window. Then a human approves.

Demotion is immediate - three guardrail violations and the agent drops a level. No review. No appeal. Authority is revoked the moment the agent demonstrates it shouldn't have it.

In the trading agent

The bull scorer starts at L0 - it can only apply predefined scoring rules. After two weeks of accurate calls with well-calibrated confidence, it's promoted to L1 (can choose between scoring strategies). The bear scorer, meanwhile, had three consecutive overconfident endorsements that failed - it was automatically demoted back to L0 and flagged for review. The asymmetry keeps the system safe while allowing strong performers to gain real autonomy.

Why not just set a fixed autonomy level?

Because agents drift. A model that was accurate last month might degrade this month due to data shifts, market regime changes, or upstream quality issues. Fixed autonomy means you either run too conservatively forever or discover the degradation when the agent takes a bad autonomous action. Earned autonomy catches the drift through continuous KPI monitoring and responds before the damage happens.

05 Adversarial Specialization Disagreement is the signal, not the noise.

Instead of building neutral agents that try to be objective, the system uses deliberately biased agents whose tension produces better collective decisions. The biases aren't bugs - they're calibrated instruments.

The three scorers

Bull scorer: Applies full weight to positive signals, discounts negatives by ~30%. Structurally optimistic. Its job is to find every reason to be bullish.

Bear scorer: The inverse. Full weight on negatives, discounted positives. Its job is to find every reason to be cautious.

Historical anchor: Ignores current sentiment entirely. Grounds analysis in realized outcomes from comparable past situations. The contrarian that keeps the other two honest.

The research layer feeding the scorers

The scorers don't analyze raw market data directly. Five independent research analysts - fundamental, technical, sentiment, macro, and earnings - each emit independent signal scores. A research synthesizer merges the five signals into a unified per-instrument feed before the scorers see it. And a memory recall agent retrieves past trade episodes that resemble the current setup, surfacing historical precedents. Signal generation is decoupled from signal aggregation, which is decoupled from adversarial scoring. Each layer can evolve independently.

Divergence as signal

A synthesizer collects all three views and measures the spread. When the bull/bear divergence exceeds a threshold (e.g., 30 percentage points), it flags explicit dissent rather than averaging the signals. The output preserves the disagreement as structured data.

In the trading agent

Earnings release for a tech company. Bull scorer sees revenue beat and flags 78% upside probability. Bear scorer sees rising debt service costs and flags 42% upside. Historical anchor finds that similar revenue-beat-with-rising-debt scenarios have resolved bearishly 60% of the time. The spread is 36 points - above threshold. The system doesn't average to 60%. It outputs: "High divergence. Bull/bear spread exceeds threshold. Historical anchor leans bearish. Escalating with full reasoning."

Why not just build one good neutral agent?

Because averaging destroys minority signal. If three agents say "buy" at 70% confidence and one domain expert says "sell" at 90%, a neutral system produces "buy at 55%." The expert's view - which might be the most important data point - disappears into the average. Adversarial specialization ensures that a strong minority view from a high-authority agent is surfaced, not suppressed.

04 Cognitive Transactions Multi-step agent workflows that roll back cleanly.

Here's a problem that doesn't show up in demos but destroys production systems: an agent executes step one of a three-step workflow, step two succeeds, and step three fails. Now your system is in an inconsistent state - partially committed, partially abandoned - and nobody designed the recovery path.

Cognitive transactions solve this by treating multi-step agent workflows the way databases treat ACID transactions - except the "steps" are agent decisions, not SQL statements. Every committed decision is wrapped as an immutable intent object before it becomes an action. That intent passes through governance validation. And the multi-step sequence executes within a saga - a coordination pattern that defines what happens when things go wrong.

Named compensation strategies

Each step in a saga declares its own rollback strategy. Not just "undo" - the system supports five compensation modes: inverse-event (emit the opposite event), reversal-agent-confirmation (a second agent verifies the reversal), partial-only (roll back what you can, keep what's committed), forward-recover (fix the failure and continue rather than rolling back), and escalate (hand the mess to a human with full context). Sagas can nest - a top-level business process can contain sub-sagas, each with their own compensation logic.

Memory-aware compensation

This is the part that matters most for agent systems. When a multi-step transaction rolls back, the initiating agent's procedural memory is automatically reverted to its pre-transaction state. Why? Because the agent was learning from the outcome of that transaction. If the transaction is reversed, the lesson it learned is invalid. Without memory-aware compensation, you get training drift - an agent that learned from outcomes that were later reversed, silently corrupting its future decisions.

Outcome abstraction

Agents don't just produce events. They produce typed outcomes - transactional intents, recommendations, questions, and approval requests. Each outcome type has its own dispatch handler, audit treatment, and validation rules. A recommendation doesn't pass through the same governance gates as an intent to execute a trade. A question doesn't require the same audit trail as a commitment. The taxonomy of what agents produce is richer than "event or not-event" - and the governance layer knows the difference.

In the trading agent

A trade execution is a three-step saga: (1) consensus approves a position, (2) position sizer commits the size, (3) order router submits to the broker. If the broker rejects the order, step 3 fails. The saga compensates: step 2 reverses the position sizing (inverse-event), step 1's consensus decision is logged as "approved but not executed" with the rejection reason, and the portfolio state manager recalculates. The agents' procedural memory reverts - no agent learns "this signal pattern leads to a successful trade" when the trade was actually rejected. The system stays consistent even when the external world doesn't cooperate.

Why not just handle failures in application code?

Because application-level error handling doesn't compose. When you have ten agents in a multi-step workflow, each with its own failure modes, writing custom recovery logic for every combination of partial failures is combinatorially impossible. Named compensation strategies make rollback a declaration, not an implementation. The saga fabric handles the complexity so individual agents don't have to understand the full recovery graph.

03 Weighted Consensus Not all votes are equal. Not all ties are failures.

When agents form views on a proposal, those views carry weight based on three factors multiplied together:

weight = domain_authority x confidence x trust_score

Domain authority - how expert is this agent in this specific domain? A risk agent has high authority on risk-related proposals, low authority on sentiment analysis.

Confidence - how certain is the agent about this particular call? An agent that's 0.5 confident carries half the weight of one at 1.0.

Trust score - how reliable has this agent been historically? Updated via exponential weighted moving average. Agents that are consistently wrong see their influence diminish automatically.

Three-phase resolution

Submit: A proposer posts a proposal with domain scope and confidence. Respond: Qualified agents endorse, challenge, or abstain - each response weighted. Resolve: Sum endorsement weights, sum challenge weights. Endorsements win = approved. Challenges win = rejected. Tied = escalated to human with full reasoning.

Programmable consensus policies

Different decisions deserve different consensus shapes. A high-stakes trade proposal might require weighted quorum from all three scorers. A routine rebalance might need only count-based quorum from the portfolio agents. Consensus rules are configurable per outcome kind - quorum size, vote-weighting algorithm, and resolution function can all be tuned for the decision's risk profile. This means governance scales with the stakes.

The calibration loop

A forecast calibration agent sits alongside the consensus engine. It tracks each scorer's trailing accuracy via exponential weighted moving average. When a scorer's accuracy degrades below threshold, the calibrator challenges the consensus on the blackboard - effectively saying "I don't trust the inputs to this decision." When accuracy degrades AND dissent is high for a specific instrument, the system arms a human-in-the-loop flag that parks trades for manual review. This is meta-learning - the system learns which scorers to trust under which market conditions.

Live example - try it
Bull Scorer
-
Bear Scorer
-
Historical Anchor
-
Click "Run" to simulate a consensus round
Why not just use majority voting?

Because three low-confidence generalists shouldn't outvote one high-confidence domain expert. Majority voting counts heads. Weighted consensus counts credibility. A single agent with 0.9 domain authority, 0.95 confidence, and 0.9 trust (weight: 0.77) should outweigh two agents with 0.3 authority, 0.5 confidence, and 0.6 trust (weight: 0.09 each, total: 0.18). The math preserves expertise.

02 Shared Cognitive Workspace Agents observe and contribute. Nobody directs.

Instead of passing messages through a central orchestrator, agents read from and write to a shared workspace - a common information space where observations, proposals, and results are visible to every agent with appropriate access.

This is an evolution of the blackboard architecture from 1980s AI research (Hearsay-II, HASP). The original concept had three flaws: a single bottleneck controller, flat global state with no isolation, and synchronous knowledge source activation. This design solves all three.

What changed since the 1990s

No controller. The runtime is a batch processor, not a planner. It doesn't decide which agent acts next - agents self-activate based on what they observe.

Immutable entries. Once posted, entries are frozen. Updates create new versions. This prevents the state corruption that made classic blackboards fragile.

LLM reasoning. 1990s blackboard agents could only pattern-match against structured data. Foundation model-powered agents can observe unstructured information, reason about ambiguity, and contribute contextually without being told exactly what to look for. The architecture was always sound - the agents weren't ready.

In the trading agent

An earnings event lands on the workspace. The bull scorer doesn't wait to be called - it observes the event, recognizes it falls within its domain, and contributes a scored assessment. Simultaneously, the bear scorer and historical anchor observe the same event and contribute their own assessments. The risk agent sees all three assessments appear and contributes a portfolio exposure check. None of these agents were sequenced by a workflow. They activated because they saw something relevant.

Spaces as bounded contexts

Each workspace is a named bounded context with runtime enforcement - not just a documentation convention. A space owns its private event mesh, its own blackboard, an autonomy ceiling that caps how much independence any agent inside can have, and an explicit ingress/egress contract that defines what events cross the boundary. Think of it like microservices, but for cognitive workspaces. The trading app uses separate spaces for market data, research, intelligence, portfolio management, execution, and risk monitoring - each with its own governance rules.

External runtime adapters

A space can host agents implemented in external runtimes - managed agents, third-party SDKs, even agents built on different frameworks entirely. The workspace enforces governance, budgets, and audit across the boundary regardless of where the agent code lives. The platform provides the substrate; agents can come from anywhere.

Why not just use an orchestrator like LangGraph?

Orchestrators encode a workflow: step A feeds step B feeds step C. That works when you know the sequence in advance. But the most valuable agent behaviors are emergent - an agent discovers something unexpected and contributes an insight nobody planned for. An orchestrator can't handle emergence because it's built to execute plans, not adapt to discoveries. The shared workspace lets agents respond to the situation as it develops.

01 Event Substrate Events are the common language. Agents talk to the stream.

Everything in the system - every observation, inference, proposal, decision, and action - is expressed as a published event on a content-based pub/sub mesh. No agent queries another directly. The event stream is the cognitive substrate.

Event anatomy

Each event carries more than just a payload. Kind classifies it cognitively - perception, inference, proposal, decision, action, hypothesis - so agents can filter by cognitive type. Caused_by is a multi-parent list creating the causal DAG. Confidence propagates from the source agent into consensus weighting. Classification enforces data security - restricted events never reach lower-clearance agents. Hypothetical flag isolates what-if analysis from production streams.

Three-layer filtering

Agents subscribe with a three-layer filter: domain lookup at O(1) eliminates ~80% of irrelevant events immediately, tag matching via inverted index handles set operations, and optional custom filters handle edge cases. The ordering ensures cheap checks run first.

Exactly-once delivery

Mesh-level deduplication enforces exactly-once delivery within a configurable window. A deduplication index with TTL is consulted at publish time. In strict mode, duplicate or dropped events raise typed exceptions rather than being silently swallowed - making "exactly once" a transport property, not a developer hygiene rule.

Atomic commit with durable outbox

A durable outbox lets agents commit business state and announcement events atomically in the same transaction. A background relay drains to the mesh with idempotent retry and deterministic dedup keys. This eliminates the dual-write drift that haunts every event-sourced system - the classic problem where your database says one thing and your event stream says another.

Failure handling

If an agent crashes mid-processing, events remain unacknowledged and are re-consumed on restart. A dead-letter queue catches events that fail after max retries. Rate limiting per publisher prevents one noisy agent from starving the mesh. The system degrades gracefully rather than failing catastrophically.

In the trading agent

A market data feed produces price events tagged domain:market.equity with kind:PERCEPTION. The bull scorer subscribes to equity market perceptions. It receives the event, produces an inference (kind:INFERENCE) with a confidence score, and publishes that as a new event. The synthesizer subscribes to inferences from all scorers. The risk agent subscribes to proposals. Each agent sees only what's relevant to its domain - the rest is filtered before it even arrives.

Why not just use function calls between agents?

Direct function calls create tight coupling. Agent A must know Agent B exists, know its interface, and handle its failures. In an event-driven system, agents are completely decoupled. You can add, remove, or replace any agent without touching the others. The event stream means the system is modular by design, not by discipline.

System Architecture

The complete trading agent pipeline. Click any component to see its role, inputs, and outputs.

Self-Improvement
Causal Attribution
Simulation Runner
Strategy Evolution
Mining Observer
Market Data
Price Stream
News Stream
Earnings + Macro
Research
5 Analysts
Fund · Tech · Sent · Macro · Earn
Synthesizer
Memory Recall
Intelligence
Bull
Bear
Hist.
Blackboard Consensus
Calibrator
Portfolio
Portfolio Mgr
Position Sizer
Trade Guard
Execution
Order Router
Fill Reconciler
Outcome Analyzer
Risk Monitoring (continuous)
Stop-Loss
Kill Switch
Position Limits
◗ Episodic Memory
◗ Procedural Memory
◗ Causal Graph
◗ Audit Log

This is the architecture I've been building as a personal research project - a way to test whether the principles I've been writing about in this series actually hold up against real market data. The stack isn't theoretical. It runs. It processes live market events, coordinates specialized agents with weighted consensus, and makes trading decisions that I can trace from market signal to execution.

It's also not finished. I'm still learning where the architecture breaks down, where the theory doesn't survive contact with production data, and where the design needs to evolve. I'll share more about the implementation - including failure modes and real results - in the final piece of this series.

If you've been following along from Part 1, you've now seen the full conceptual stack: from the event substrate that gives agents a common language, through the shared workspace that enables emergent coordination, the consensus protocol that structures collective decisions, the cognitive transaction fabric that makes multi-step workflows durable, the adversarial specialization that makes disagreement valuable, the earned autonomy that keeps the system safe, and the observability layer that makes every decision traceable.

The intelligent systems of the future won't be built by wrapping agents around existing workflows. They'll be built on architectures designed from scratch for how intelligence actually coordinates - through shared context, weighted judgment, and earned trust.

If you're building in this space and want to go deeper on any of these patterns - or if you see flaws in the thinking - I'd welcome the conversation. Reach out at hello@prakulsharma.ai.

All views expressed in this article are solely my own and do not represent or reflect the views, positions, or policies of my employer. This is independent thinking on open industry challenges, shared as a personal research interest. Not financial advice.

← All Perspectives