Architecture — PayAna Market Sentinel

Mission

Build a small, inspectable Agent OS workflow that improves the quality of market reasoning without needing trading authority. The system is deliberately split between observation, deterministic measurement, hypothesis/falsification guidance, and human/AI interpretation.

System map

MCP-capable AI client │ │ Binance Agent OS MCP (public Market Data capability) │ Account / Trade / Transfer not needed by PayAna ▼ Binance market evidence │ ├─ ticker ├─ order book ├─ candlesticks └─ funding/mark price when available │ ▼ PayAna Falsifier Skill (SKILL.md) │ ├─ validate currentness ├─ compute metrics ├─ winning hypothesis ├─ opposite hypothesis ├─ alternative explanation ├─ falsifiers └─ negative-space / missing-context audit │ ▼ Evidence briefing — NO_TRADE_DECISION

The deployed web cockpit is a reference implementation and live demo of the deterministic evidence layer:

Browser │ GET /api/analyze?symbol=... ▼ Hono / Val Town │ ├─ strict symbol allowlist ├─ no-store API responses ├─ best-effort per-runtime rate limit ├─ CSP / nosniff / frame denial / permissions policy │ ▼ data-api.binance.vision ├─ 24h ticker ├─ top-20 depth └─ 36 × 5m klines

Runtime routing decision

During runtime discovery on 2026-09-07:

  • api.binance.com from the Val Town runtime returned HTTP 451 (restricted runtime location).
  • data-api.binance.vision returned HTTP 200 for the required public market-data reads.
  • The reference web implementation therefore routes public reads through data-api.binance.vision.
  • The official Agent OS MCP endpoint returned HTTP 401 on an unauthenticated initialize, with OAuth Protected Resource Metadata pointing to https://agent.binance.com.
  • Authorization-server metadata advertises Authorization Code + PKCE (S256), public-client token auth (none), and Client ID Metadata Document support.

These facts are intentionally kept separate:

PUBLIC_MARKET_API_WORKS != AGENT_OS_MCP_CONNECTION_PROOF OAUTH_FLOW_READY != USER_AUTHORIZED_SESSION AUTHORIZED_TOOL_CATALOG != TOOL_CALL

Binance's current MCP documentation classifies Market Data as public, no auth. PayAna therefore does not need Account, Trade or Transfer authority to perform its intended read-only workflow. However, a direct 2026-07-28 transport probe on 2026-09-07 showed an important distinction: unauthenticated server/discover reached Binance but returned JSON-RPC Method not found, while unauthenticated tools/list returned HTTP 401 with OAuth Protected Resource Metadata. Therefore public Market Data capability does not imply an unauthenticated MCP tool catalog on this deployed server; the MCP connection itself is currently authorization-gated. A hackathon connection proof should use a supported MCP client and visibly show a Binance MCP Market Data tool being used. The optional PayAna CIMD/PKCE path is a connection-verification experiment, not evidence of private account permission.

Evidence model

Each analysis produces a source receipt. Source failures are visible in the response. The system does not silently substitute stale or fabricated values.

Evidence state:

  • PASS: all three reference sources succeeded.
  • PARTIAL: one or two reference sources succeeded.
  • FAIL: all reference sources failed.

A source receipt includes source name, URL, HTTP result, duration and failure reason where applicable. An HTTP-success response is also shape-validated before it becomes evidence. Malformed ticker/order-book/candle payloads are demoted to source failure.

Missing-data policy is fail-visible: unavailable derived metrics become null, missing sources are excluded from directional aggregation, and no missing value is converted to numeric zero. If only non-directional ticker evidence survives, the system returns INSUFFICIENT_EVIDENCE rather than fabricating a neutral score.

Descriptive metrics

The reference implementation exposes the formulas in the API response itself under method so a reviewer can reproduce them.

The directionalScore is a bounded heuristic combining order-book imbalance and two momentum horizons. It is intentionally described as a descriptive pressure score.

The stabilityScore decreases as volume anomaly, short-horizon volatility, spread or missing sources increase. It is explicitly not a calibrated probability.

Security boundaries

Present controls

  • public/read-only data only;
  • fixed symbol allowlist;
  • no arbitrary upstream URL forwarding;
  • no Binance API keys, access tokens or refresh tokens durably stored;
  • optional OAuth state stores only a one-time random state plus PKCE verifier, with 10-minute TTL and 500-row cap;
  • authorization state is single-use and concurrent replay has exactly one winner in testing;
  • no Trade, Account or Transfer endpoint;
  • no inbound POST action route;
  • no wallet address capture;
  • Cache-Control: no-store for APIs;
  • CSP;
  • X-Content-Type-Options: nosniff;
  • X-Frame-Options: DENY;
  • restrictive Permissions-Policy;
  • per-runtime inbound request bucket;
  • explicit NO_TRADE_DECISION response contract.

Limits

The in-memory rate limiter is a best-effort demo control, not a distributed security boundary. A horizontally scaled/serverless deployment would require a shared rate-limit store.

No statement in the web cockpit proves that the Binance Agent OS MCP connection has been authorized. MCP authorization is a separate external state.

Validation

Current release audit executes 189 assertions plus 35 rate-limit mutation steps (224 total checks). Detailed evidence is in docs/TEST_EVIDENCE.md.

Coverage includes:

  • five allowlisted symbols;
  • freshness check on ticker timestamp;
  • price > 0;
  • spread >= 0;
  • order-book imbalance in [-1, 1];
  • stability score in [0, 1];
  • stability language explicitly says it is not a calibrated probability;
  • three source receipts;
  • minimum candle series;
  • invalid/injection-like symbols rejected;
  • write-like POST route rejected;
  • unknown routes return 404;
  • OAuth/CIMD/PKCE request construction, state/replay/issuer controls and callback-negative paths;
  • MCP 2026-07-28 headers plus _meta protocol/client capability identity;
  • synthetic tool catalogs containing safe Market Data and dangerous Account/Trade/Transfer-like tools;
  • proof that no tools/call occurs automatically;
  • OAuth state TTL, concurrent one-time consumption and durable-row cap;
  • rate limiter mutation test: requests 1–30 pass and 31–35 are rejected with 429.

The rendered UI is separately checked because server tests do not prove browser execution. A JavaScript-rendering extraction successfully found React-only selectors after CSP hardening, including source receipts; interactive/screenshot browser automation is currently blocked by external TinyFish/Firecrawl credit state and is not claimed as completed.

Negative controls and falsification

The architecture is designed around a stricter invariant than “the dashboard loaded”:

  • HTTP_200 != VALID_MARKET_EVIDENCE
  • SCREENSHOT != BEHAVIOR_PROOF
  • MODEL_CONFIDENCE != CALIBRATED_PROBABILITY
  • MARKET_DATA_READ != TRADING_AUTH
  • MCP_ENDPOINT_KNOWN != MCP_SESSION_AUTHORIZED
  • FETCH_FAIL != ZERO
  • CURRENT_PRESSURE != FUTURE_PRICE

This is the main technical thesis of PayAna: an agent should not only produce an answer; it should expose how that answer can fail.