Most writing about AI agents still treats reliability as a model problem. Better weights, better prompts, better evals. That work matters. It is also incomplete.
Once an agent has to operate across more than one surface — a private workstation that can see a chart, a hosted observation plane that cannot, a VPS scheduler that keeps running when nobody is watching — the hard problems move into software engineering. Who is allowed to see what. Which component is allowed to mutate state. What evidence you keep when a scan fails at 03:14. Whether a browser reconnect can invent a second lifecycle transition.
This is the work we have been doing on Leverage since the Learning / Playbook Memory layer landed. Not another learning post. This one is about making a chart-reading agent system trustworthy enough to observe, audit, and recover.
## The problem is multi-surface, not multi-model
Leverage reads a rendered TradingView chart, combines it with market structure, trusted spot, higher-timeframe context, news, calendar risk, and trade history, and returns structured decisions. The interesting engineering constraint is not that a language model is in the loop. It is that the same decision system must be honest across surfaces with different capabilities.
There are at least four distinct planes:
1. The Chrome extension beside TradingView. It can capture pixels, run the Pulse scheduler, accept trades, and mutate private desk state. 2. The VPS Chrome workstation. Same extension capabilities, but unattended: a persistent visible TradingView session so Pulse can keep scanning when a human is offline. 3. The hosted Floor at `/office`. Same Floor UI code as the extension, served by the Go backend, hydrated by an authenticated Floor API. It is an observation surface. It cannot capture a chart or own the scanner. 4. Telegram. Compact distribution. Intentionally a reduced view of the system, not the system itself.
If those planes collapse into one mental model — "the AI product" — you get the wrong security and reliability instincts. A control that is safe in the extension can be dangerous on the web. A payload that is useful for a trader can be too private for a public observer. A state transition that looks fine in a live session can become a ghost if the service worker dies mid-upload.
Trustworthy agent systems start by drawing those boundaries in code, not in product copy.
## Analysis authority is an ordered list, not a vibe
When inputs disagree, Leverage does not ask the model to "use its judgement about which source to trust." It follows an explicit authority order:
1. Current visible chart and current trusted price 2. Deterministic trade lifecycle and mechanical TP/SL state 3. Canonical active trade fields 4. Current news, macro calendar, and session context 5. Fresh Daily/4H Market Map 6. Previous Pulse read and session continuity 7. Historical evidence and shadow learning diagnostics
Fresh evidence overrides stale narrative. Historical memory is not allowed to change mechanical target or stop detection. That separation is the same design principle we learned the hard way earlier: models handle interpretation; code handles facts.
The practical consequence for agent ops is that reliability work is mostly about protecting the higher-authority layers. Capture integrity, spot crossings, lifecycle idempotency, and auth scoping are not "infra around the AI." They are the AI system's ground truth.
## Capture integrity before the model sees anything
Automatic Pulse scans do not succeed because an image arrived. The extension sends capture metadata: page title, URL, captured time, freshness, image hash, and page quote. The backend rejects an automatic read when metadata is missing, the image hash is missing, freshness is not `fresh` or `confirmed_unchanged`, the capture is more than five minutes old, or the timestamp is materially in the future.
That sounds pedantic until you operate a chart-reading agent on a remote desktop. Stale frames, duplicate frames, and soft-dead browser sessions are ordinary failure modes. If you let the model narrate a chart that is no longer the market, you have not built an agent. You have built a confident historian of the wrong moment.
A shared analysis lane also prevents Pulse, manual requests, and other workflows from overlapping model calls. A scan stuck for more than three minutes is treated as stuck and retried. Agent reliability here looks less like clever prompting and more like concurrency control plus freshness contracts.
## The hosted Floor is an observation plane on purpose
The web product is not a separately redesigned dashboard. The backend serves the actual extension Floor from `/office` and its assets under `/floor/`. A browser adapter replaces `chrome.storage.local`, polls the authenticated Floor API on an eight-second cadence, and hydrates Pulse runtime, reads, trades, signals, feeds, calendar, learning diagnostics, Market Map state, and identity.
What it deliberately does not do matters more. Chart-dependent controls stay disabled. If a hosted client tries to exercise an extension-only action, the adapter returns a hard failure: the control needs the Chrome extension and an open TradingView chart. That is not a temporary UX gap. It is a trust boundary. Observation must not silently upgrade itself into actuation.
This is one of the clearer lessons from building agentic products: reuse the same UI code across surfaces, but do not reuse the same capabilities. Capability leakage is a reliability bug with a security face.
## Observer sanitization is a schema, not a filter afterthought
There is a public observer endpoint, `GET /api/leverage/observer`, that publishes sanitised desk publications and health. The point is not "hide some fields if we remember." The point is a narrower type.
`PublicPulseEvent` and `PublicDeskPublication` are deliberately smaller than private analysis episodes and trade cases. They carry market-facing setup state: asset, verdict, direction, levels, headline, paper resolution status, ambiguity flags, realised R when it belongs to the published paper record. They do not carry user identity, prompts, conversations, notes, request context, or a trader's private journal.
Public desk publications are also not user-scoped the way private trade lists are. They are the shared desk ledger: calls the system published, not personal behaviour a user took. Paper lifecycle can attach so the observation plane stays honest about whether a published setup later triggered, hit a target, stopped, expired, or went ambiguous. Dollar P&L and private notes stay out.
That distinction — desk publication versus private taken-trade journal — is the kind of boring schema work that decides whether an agent system can be shown to other people without becoming a data leak with a Three.js skin.
## Auth boundaries: principal from token, never from the body
Private APIs authenticate a principal from the Bearer token. Passwords are bcrypt. Auth tokens are stored as SHA-256 hashes with a short visible prefix. Roles split `owner` and `tester`. Password sessions last seven days. The legacy `SIGNAL_HTTP_BEARER_TOKEN` still bootstraps an owner credential for compatibility, but the HTTP server refuses to start if signal HTTP is enabled and that token is empty. No silent unauthenticated exposure.
The rule that matters for agent systems: all private database reads are scoped by the principal resolved from authentication. The backend does not trust a request-provided user ID. Lifecycle uploads resolve identity from the server token. Offline queues in the extension can retry events after a service-worker restart; they cannot smuggle a different user identity through the body.
This is ordinary auth engineering. It becomes agent-specific when the agent itself is a writer of state. Every Pulse read, lifecycle event, and flight-recorder append is an authenticated write. If your agent can invent identity, your audit trail is fiction.
## Trade lifecycle is the recoverability object
Leverage separates paper setups from taken trades and refuses to merge them into one performance statistic. Each trade case links back to the analysis episode that created it. Events use stable client-generated IDs and are idempotent per user. Replaying an offline event cannot create another lifecycle transition.
That idempotency is not an API nicety. Manifest V3 service workers suspend. Networks drop. Remote desktop sessions wobble. An agent that cannot safely replay its own state transitions is not recoverable; it is intermittently creative.
Mechanical tracking follows the same rule we already learned for stops and targets. The spot poller observes crossings without asking the model whether a numerical level was hit. If one observed price jump could have crossed both target and stop between polls and the order cannot be established, the case is marked ambiguous and excluded from clean expectancy reporting. Ambiguity is a first-class state, not an awkward null.
Offline reliability sits beside that: lifecycle uploads queue locally when the backend is unreachable, capped and persisted in Chrome storage, retried by alarm, surviving service-worker restarts. Recoverability for agents is less about checkpointing the model and more about making the surrounding state machine append-only, idempotent, and replay-safe.
## Pulse flight recorder: append-only ops for agent behaviour
The flight recorder exists because "the model returned something" is not an operations history.
Pulse flight events are authenticated, user-scoped, and append-only at the database layer. Updates and deletes are rejected by triggers. Recording the same client `event_id` is a successful no-op. Events carry flight ID, optional episode and scan links, asset, strategy, event type, spot, verdict, candidate and condition state, levels, watch condition, and capture freshness.
The Floor can reconstruct recent setup lifecycles from those immutable events. That is the agent equivalent of a flight data recorder: not a prettier log viewer, but a durable timeline of scheduler and decision transitions that survives the UI refreshing, the service worker dying, or a human asking three days later why a WAIT never armed.
If you are building agent ops tooling, this is the pattern worth stealing. Do not only store final answers. Store the transitions that produced them, under auth, with idempotent IDs, in a store that refuses to be quietly rewritten.
## Failure modes we designed around
These are the failure modes that shaped the architecture. None of them are exotic.
**Stale perception.** The workstation is still up, but the chart is old, duplicated, or from the wrong moment. Mitigation: capture freshness contracts and rejection before model invocation.
**Capability confusion.** A hosted observer looks like the full product and tries to act like one. Mitigation: shared UI, split capabilities, hard adapter failures for extension-only actions.
**Private state leakage.** Prompts, notes, identity, and personal P&L hitch a ride on "transparency." Mitigation: narrower public types and a desk-versus-journal split.
**Identity spoofing through agent writes.** A client supplies the user it claims to be. Mitigation: principal from token only; scoped reads and writes.
**Double application after reconnect.** Offline retries recreate lifecycle transitions. Mitigation: client event IDs, idempotent inserts, append-only recorder semantics.
**Model opinion about mechanical facts.** The agent "thinks" a stop was or was not hit. Mitigation: deterministic spot observers and ambiguous outcomes when the tape is inconclusive.
**Overlapping cognition.** Two scans reason about the market at once and diverge. Mitigation: shared analysis lane, stuck-scan detection, cadence control, candidate wakeups from trusted spot instead of blind polling alone.
**Authority inversion.** Old narrative or memory outranks the live chart. Mitigation: explicit analysis authority order, with mechanical lifecycle above continuity and historical evidence.
## What we instrumented, and why it is not vanity telemetry
Instrumentation in an agent system should answer operator questions, not produce dashboards for their own sake.
We care about:
- Whether the model gateway is ready, in-flight, or circuit-open
- Whether captures were fresh enough to analyse
- Which Pulse flight transitions occurred for a setup
- Which lifecycle events applied, duplicated, or marked a case ambiguous
- What the public observer can see versus what only an authenticated desk can see
- Whether the hosted Floor is hydrated from server state or pretending to own local scanner state
The model gateway itself has concurrency limits, bounded retries, fallback routing, and a circuit breaker with cooldown. Raw provider failures are translated into product errors so testers do not see command output, local paths, or keys. That is part of trust too. An agent system that leaks its machinery under failure trains people to ignore alerts or paste secrets into chat logs.
## Lessons for AI and software engineering
A few principles survived contact with the system:
**Surfaces are security domains.** If two UIs share pixels but not powers, encode the difference. Do not hope the operator notices.
**Trust boundaries need types.** Sanitisation that lives only in ad hoc response shaping will drift. Narrow public structs beat filter glossaries.
**Recoverability is about events, not transcripts.** Chat logs help humans. Idempotent lifecycle and flight events help the system survive itself.
**Ambiguity is better than false certainty.** Marking a case ambiguous is an engineering feature. Forcing a winner from an under-sampled price jump is a reliability bug dressed as decisiveness.
**Agent ops is mostly classical systems work.** Authn/z, freshness, queues, idempotency, circuit breakers, append-only logs. The model is the interpretive core. The surrounding machinery decides whether that core can be trusted in production.
**Do not let observation become actuation.** Hosted watchers are valuable. They become dangerous when they quietly inherit workstation privileges.
## Where this still stops
We are not claiming the agent is always right. Deterministic controls reduce lifecycle and state errors; they do not guarantee good analysis. The production perimeter still has deferred hardening work. The web Floor remains an observer, not a replacement scanner. Pulse still depends on a persistent visible TradingView browser. Playbook Memory remains evidence collection and shadow evaluation until readiness thresholds say otherwise.
Those limits are part of the trust story. A trustworthy agent system is one whose boundaries you can state without flinching.
The work since Learning has mostly been this: make Leverage auditable across surfaces, keep private desks private, keep public observation honest, and make Pulse recoverable when the world is messy. That is software engineering for agentic systems. The model is necessary. It is not sufficient.
