Every policy pack published to the registry has a content hash.
When an author publishes, they call PalisadeRegistry.publish() on Robinhood Chain with a keccak256 hash of the canonical policy JSON. The registry API verifies the match before the pack goes live. The on-chain record is the source of truth.
When you pull a pack, palisade init --pack slug fetches the content JSON from the registry API and recomputes the hash locally. If it does not match what is on-chain, the pull is rejected before anything touches your policy file.
You are not trusting the API. You are trusting the chain, and verifying against it locally.
Once the pack passes verification, it loads into your local policy.yaml as a starting point. You review it, edit it if needed, and apply it yourself. Nothing auto-applies. Nothing reaches into the enforcement path without your confirmation.
The registry handles distribution. The chain handles integrity. Your machine handles enforcement.
@robinhoodapp $PLSD
Rule updates and enforcement are separate concerns. PALISADE keeps them that way.
You update policy.yaml locally, through the CLI or the local web UI at localhost:7443. The gateway validates the new policy against the zod schema inline, shows you a diff, and hot-reloads it into the engine on confirm. No remote call. No restart required.
From that point forward, every order evaluation runs against the new rules, still in-process, still in under 1ms, still with zero network dependency.
The policy-pack registry on Robinhood Chain is for discovery and distribution, community rulesets you can pull and apply. But pulling a pack is a deliberate user action, not an automatic sync. Nothing in the enforcement path polls the registry or waits on a remote config fetch.
You decide when rules change. The engine enforces whatever is loaded. The two operations never share a critical path.
@robinhoodapp $PLSD
Almost every company that goes on to change the world starts out looking small, unproven, and easy to overlook. In our roadshow video, Shiv and I talk about why that stage matters and how Robinhood Ventures Fund II is getting everyday investors in before the rest of the world might be paying attention.
API gateway auth has one job: verify the request before it passes through. To do that, it calls out. Token validation, policy lookup, rate limit check, all of it hits a remote service.
That round trip is the gap.
Network latency, service outage, cold start, any of it delays or drops the check. Some architectures fail open when the auth service is unreachable. The request goes through because blocking everything felt worse than the risk.
PALISADE has no round trip in the enforcement path.
Rules are loaded at startup. State is in memory, reconciled locally. The policy engine is a pure function. No token to validate remotely, no policy server to reach, no external call between the order and the verdict.
The check cannot be delayed by latency. It cannot be skipped by an outage. It cannot fail open because there is nothing to fail.
Zero-network dependency is not a performance optimization. It is what makes the guarantee unconditional.
@robinhoodapp $PLSD
Most systems outsource their decisions. PALISADE does not.
The rules live on your machine. The account state lives on your machine. The enforcement decision happens in-process, in under 1ms, with no network call required.
If every external service goes dark, the next order still hits the same wall.
That is not a resilience feature. That is the architecture.
@robinhoodapp $PLSD
If the RPC node is unreachable, the pull fails closed.
PALISADE does not apply an unverified pack. No fallback, no skip-verification flag, no cached approval. The content hash check against Robinhood Chain is a hard requirement for any new pack being applied.
Your existing policy stays loaded. Enforcement continues uninterrupted.
The RPC only matters at the moment you choose to pull something new. It has no role in the enforcement path. A node outage cannot degrade a running gateway.
When the RPC comes back, you retry the pull. The wall held the whole time.
@robinhoodapp $PLSD
Most systems outsource their decisions. PALISADE does not.
The policy engine evaluates every order call against two things: the rules you set in policy.yaml and a live snapshot of your account state. Both live on your machine. Neither requires a network call to exist.
The state snapshot is maintained by the State Tracker, reconciling directly from @robinhoodapp's read tools every 15 seconds and after every mutating call. Equity, exposure, daily notional, PnL, order rate windows, all written to local SQLite in real time. The engine reads from memory. Evaluation is O(1), under 1ms, no round trips.
The rules are declarative YAML validated by zod at startup. Once loaded, they are in-process. No policy server to query, no remote config to fetch, no dependency on anything outside the binary.
This is what makes the gateway self-contained. The enforcement decision, allow, clamp, or deny, happens entirely within the process, against data the process already holds. If every external service goes dark, the next order call still hits the same wall.
That is not a resilience feature bolted on. It is what the architecture was built around.
$PLSD
Know the business, not just the ticker.
Company financials now live in agentic trading. Ask your agent how revenue, profits, and growth have moved over time. Available for everyone in the U.S. today.
Local SQLite means the gateway survives everything except a deliberate shutdown.
If the process crashes, restarts, or the machine reboots, the State Tracker picks up exactly where it left off. Daily notional consumed, realized PnL, order rate windows, last-loss timestamp, all of it persists. Without that, a restart mid-session would reset every counter to zero and the policy engine would evaluate the next order as if the day had just started. A $2,000 daily cap becomes meaningless if a crash at $1,800 resets the clock.
Day boundaries roll in the user's configured timezone, not the server's. The limit that matters is the one that matches how the user actually thinks about their trading day.
From a user experience standpoint, none of this is visible. The gateway starts, loads state, and continues. No manual reconciliation step, no re-entry of positions, no warning that limits have been lost. The wall holds across sessions without the user doing anything.
It also means there is no external dependency in the critical path. No cloud database to be unavailable, no network call required to know whether an order is inside limits. The decision happens locally, against local state, in under 1ms.
Hey Gm @RobinhoodApp CT
It is 2:47am. Your agent is running. The cloud policy server your traditional firewall depends on goes unreachable, a routine outage, 4 minutes of downtime.
In that window, the agent receives a prompt injection through stale market data. It reasons its way into a $15,000 position in a single illiquid name. The network firewall sees valid MCP traffic. The cloud policy check never happens. The order goes through.
By the time the outage resolves, the position is open and moving against you.
With PALISADE, that scenario does not exist.
The policy engine runs in-process on your machine. No cloud call required to evaluate an order. The state snapshot is local. The rules are local. The decision is local. An outage anywhere in the network changes nothing about whether that $15,000 order clears the position size limit, the daily notional cap, or the symbol allowlist.
It does not. The order is denied. The reason is logged. The hash is chained.
The cloud registry being down, the anchor RPC being unreachable, none of it touches the enforcement path. The wall holds because it does not depend on anything outside the machine it runs on.
@robinhoodapp $PLSD
Robinhood's agentic rollout added 70,000+ agent-enabled accounts in the first weeks. Their own disclosures warn agents can misread instructions or act on stale data. Account-level controls are still just "fund it or disconnect it." That gap is what we built for.
Palisade team.
Most systems lose state on a restart. PALISADE does not.
Every metric the policy engine depends on, daily notional consumed, realized PnL, order rate windows, last-loss timestamp, is written to local SQLite in real time. When the gateway restarts, it loads that state and continues. No counters reset. No limits reset. The wall holds across sessions without any manual step from the user.
That matters in practice. A $2,000 daily cap is meaningless if a crash at $1,800 resets the clock. Bun's native SQLite driver keeps that from happening with zero external dependency in the critical path.
Day boundaries roll in the user's configured timezone, not UTC. The limit matches how the user actually thinks about their trading day.
No cloud database. No network call required to evaluate an order. State is local, the decision is local, latency stays under 1ms.
The gateway is self-contained by design. If everything else goes down, the firewall keeps running.
@robinhoodapp $PLSD
Traditional firewall architectures are network-dependent by nature. They sit at a perimeter, route traffic through centralized inspection layers, and rely on upstream services, cloud backends, policy servers, logging infrastructure, to function. When any part of that chain goes down, the firewall degrades. In some architectures, a backend failure means traffic passes uninspected. The resilience of the system is only as strong as its weakest external dependency.
PALISADE inverts that model entirely.
The gateway is a single self-compiled Bun binary. It runs on the user's machine or their own VPS. Policy evaluation happens in-process against an in-memory state snapshot. State persists in local SQLite with no external write path. The only outbound connections are the upstream Robinhood Trading MCP for broker reads and, optionally, an hourly anchor write to Robinhood Chain. Neither is required for the policy engine to function.
If the cloud registry goes down, every gateway keeps running. If the anchor RPC is unreachable, orders are still evaluated and logged locally. If the network drops between polls, the last reconciled state holds until connectivity returns. There is no central point of failure that takes the firewall with it.
Traditional architectures protect the perimeter and accept that the protection depends on infrastructure staying live. PALISADE protects the action and accepts no such dependency. The wall holds because it runs where the decisions happen, not somewhere else on the network.
Most systems lose state on a restart. PALISADE does not.
Every metric the policy engine depends on, daily notional consumed, realized PnL, order rate windows, last-loss timestamp, is written to local SQLite in real time. When the gateway restarts, it loads that state and continues. No counters reset. No limits reset. The wall holds across sessions without any manual step from the user.
That matters in practice. A $2,000 daily cap is meaningless if a crash at $1,800 resets the clock. Bun's native SQLite driver keeps that from happening with zero external dependency in the critical path.
Day boundaries roll in the user's configured timezone, not UTC. The limit matches how the user actually thinks about their trading day.
No cloud database. No network call required to evaluate an order. State is local, the decision is local, latency stays under 1ms.
The gateway is self-contained by design. If everything else goes down, the firewall keeps running.
@robinhoodapp $PLSD
Hey @RobinhoodApp
The State Tracker never derives account state from the agent's activity log. It goes to the source.
Every 15 seconds, and immediately after any mutating call clears the policy engine, the tracker fires read requests directly against the Robinhood Trading MCP: positions, orders, balances. What comes back is ground truth. The tracker uses those responses to update every metric the policy engine depends on: current equity, per-symbol exposure as a percentage of equity, daily notional consumed so far, realized PnL for the day and on a trailing basis, sliding-window order rate counters, and the timestamp of the last recorded loss.
The reason for polling after every mutating call specifically is latency. A fill can change exposure, PnL, and daily notional simultaneously. Waiting up to 15 seconds after a live order would mean the next policy evaluation runs against stale numbers. The post-call reconciliation closes that window.
Everything is written to local SQLite so a process restart does not reset daily limits mid-session. Day boundaries roll over in the timezone configured in the policy file, not UTC, so the limits match the user's actual trading day.
The agent never gets to report its own fills. The broker does.
PALISADE is open source, starting today. Self-hosted guardrails for agentic trading: you run it, you audit it, nobody else touches your keys. The code that decides whether your agent's order goes through is code you can read.
- https://t.co/Bi533zheeb
An AI model is a probabilistic system. Same input, different output. That is the point of it, and also the problem when it is holding real money.
A deterministic firewall is the opposite. Same input, same output, every time. No reasoning, no interpretation, no chance it talks itself into an exception. You set the rules once. The engine applies them without opinion.
PALISADE sits between your agent and @robinhoodapp as exactly that. Every order call hits a pure policy engine before it reaches the broker. Position limits, daily caps, drawdown thresholds. The model cannot negotiate with it because there is nothing to negotiate with.
Probabilistic systems need deterministic walls. That is the architecture.
$PLSD
Hey @RobinhoodApp
The policy engine is only as good as the state it evaluates against.
The State Tracker is what keeps that state honest. It polls @robinhoodapp's read tools every 15 seconds and after every mutating call, reconciling equity, per-symbol exposure, daily notional, realized PnL, order rate windows, and last-loss timestamp directly from the broker.
It never trusts the agent's version of events. Only broker reads count.
State persists in local SQLite across restarts so daily limits don't reset on a crash. Day boundaries are computed in the policy's configured timezone.
The engine gets a clean snapshot. The wall holds.
$PLSD
The policy engine is a pure function.
(toolName, args, accountState, clock) β Verdict
No IO. No database calls. No LLM. No side effects. You pass in the tool being called, the arguments, a snapshot of the current account state, and a timestamp. You get back a verdict: allow, clamp, or deny with a named reason.
Every rule evaluates against the in-memory state snapshot. Equity, per-symbol exposure, daily notional consumed, realized PnL, order rate windows, last-loss timestamp. All of it maintained by a State Tracker that reconciles directly from @robinhoodapp's read tools every 15 seconds and after every mutating call. The engine never trusts the agent's claims about its own fills.
Rules are AND-composed. First failing rule short-circuits with its named verdict. Evaluation is O(1). Target latency is under 1ms. The firewall adds nothing meaningful to the order path.
The FSM has three states: ARMED, THROTTLED, KILLED. Transitions are deterministic. Only a human re-arms from KILLED. No automatic reset.
Policies are declarative YAML validated by zod. The engine itself is pure TypeScript, zero IO, fully unit-testable. Every rule, every boundary value, every FSM transition has a test. This package is the product.
$PLSD
Traditional firewalls operate on network traffic. They inspect packets, filter by IP, block ports. The threat model is external, something trying to get in.
PALISADE's deterministic firewall operates on intent. The threat model is internal, your own agent making a decision you did not sanction. No packet filter catches that. No network rule stops an LLM from placing a $10,000 order because it misread context.
Most AI safety layers today are also probabilistic. Content filters, prompt guardrails, output classifiers. They work until they don't. They can be argued around, jailbroken, or simply wrong at the wrong moment.
PALISADE's policy engine is none of that. It is a pure function. Input goes in, verdict comes out, same result every time. No model in the loop, no interpretation, no edge case where it decides the rule doesn't apply.
Traditional firewalls protect the perimeter. PALISADE protects the action. That is a different problem, and it requires a different kind of wall.
@robinhoodapp $PLSD
An AI model is a probabilistic system. Same input, different output. That is the point of it, and also the problem when it is holding real money.
A deterministic firewall is the opposite. Same input, same output, every time. No reasoning, no interpretation, no chance it talks itself into an exception. You set the rules once. The engine applies them without opinion.
PALISADE sits between your agent and @robinhoodapp as exactly that. Every order call hits a pure policy engine before it reaches the broker. Position limits, daily caps, drawdown thresholds. The model cannot negotiate with it because there is nothing to negotiate with.
Probabilistic systems need deterministic walls. That is the architecture.
$PLSD
Your trade data belongs to you.
PALISADE stores every order call, every verdict, every result in local SQLite on your own machine. Nothing is sent to a server. Nothing is held by us. No third party can access it, leak it, or be compelled to hand it over.
The only thing that ever leaves your environment is a Merkle root, a single hash, anchored on Robinhood Chain once an hour. It proves your records are intact. It reveals nothing about what they contain.
Privacy here is not a policy. It is the architecture.
@robinhoodapp $PLSD
Most people don't think about guardrails until the agent does something it shouldn't.
That's exactly why we built PALISADE. A deterministic firewall between your AI model and @robinhoodapp, running entirely on your machine. No cloud dependency, no custody, nothing leaving your environment.
@RHCBuilders gets it. Running locally isn't a feature, it's the only architecture that makes this trustworthy.
$PLSD