PaperQuant has four deliberately separate boundaries.
- The browser owns interaction, live public data, and the persisted paper account.
- ChatGPT Sites owns same-origin validation, D1 metadata, quotas, idempotency, and R2 artifact references.
- The isolated
agent-testingworker on the project GCP VM owns long-running archive ingestion and trusted built-in strategy execution. It has its own PM2 process, loopback port, SQLite queue, data cache, and bearer-authenticated HTTPS boundary; it does not share or modify the VM's other PM2 services. - Hosted user-authored Python is disabled unless an independent sandbox gate passes. The local Pyodide worker is not treated as a production server sandbox.
No boundary includes a real-order adapter.
WebMCP handlers and human UI actions use the same state transitions. The registry is not a click simulator and does not keep a parallel account. The live snapshot exposes market context, candles, indicators, signals, paper state, public order book, and aggregate tape. Mutations call the same migration-aware account engine and immediately enter the normal persistence path.
D1 tables:
paper_states: versioned serialized browser session state.research_runs: immutable request metadata plus compact status/results.saved_strategies: user strategy source and SHA-256 source hash.idempotency_keys: retry-safe server mutations.lab_sessions: expiring owner snapshot plus SHA-256 observer-token hash.lab_events: sanitized, bounded human/agent/system activity records.research_cache: engine-versioned scientific input hash to immutable result/artifact metadata.
R2 keys use research-runs/{runId}/workflow-result.json.gz and contain immutable complete artifacts. The worker exposes each completed gzip artifact only through its authenticated task endpoint. Sites streams those bytes into its own ARTIFACTS binding, then stores the key in D1. The client receives keys/metadata, never a worker bearer token or storage credential.
- Sites validates a request, enforces a 30-run rolling anonymous quota, and derives an engine-versioned cache key from the scientific inputs.
- If a matching terminal artifact exists in R2, Sites creates a fresh traceable run record that references the immutable source and returns it immediately with the same scientific hash.
- Otherwise Sites creates an immutable run ID and writes a
RUNNINGrecord. If the worker is configured, Sites callsPOST /v1/task-runs; otherwise it performs a bounded public-REST preview and reportsPARTIAL_DATA. - The worker downloads official Binance monthly kline/funding partitions and daily five-minute USD-M metrics partitions, verifies each published SHA-256 checksum, normalizes timestamps, executes the deterministic engine, and produces both a compact result and a complete gzip artifact.
get_research_runpolls the worker when needed, streams the authenticated complete artifact into Sites R2, records its immutable key/cache row, and copies the compact terminal result to D1.show_run_on_chartoverlays the stored signal markers without changing the paper account.
PaperQuant does not install a separate MCP program into Codex. Its WebMCP definitions ship in the website bundle. The public root uses lib/landing-webmcp.ts for two orientation tools. /lab uses lib/webmcp.ts for 22 names, descriptions, strict schemas, annotations, validation, and execute handlers; components/PaperQuantLab.tsx binds those handlers to the live React/application state.
The built-in browser owns document.modelContext. While the top-level PaperQuant document is open, Codex can discover the registrations attached to that page and invoke them. The browser safety-checks a call and routes it back to the page handler; the handler calls the shared controller; the controller changes the real UI/account state or calls a same-origin /api/* route. Navigating away or closing the page removes that page's tools, and React's AbortController cleanup prevents stale registrations.
Codex skills are separate. A skill is an instruction package installed in Codex/a plugin; PaperQuant does not download or store Codex skills. The Site provides WebMCP tool metadata and handlers. Codex supplies its own reasoning, skills, normal browser abilities, and safety policy.
Opening /lab creates or resumes a 24-hour D1 session. The browser stores the raw owner session ID and observer bearer token; D1 stores only the observer token's SHA-256 hash. State snapshots are throttled, while workflow events are sent immediately and also broadcast within the browser. /observe/[token] polls a GET-only endpoint, renders public candles and the sanitized snapshot, and deliberately registers no WebMCP mutations. Events never include prompts, Python source, API keys, idempotency keys, or private account data.
All WebMCP operations return the documented envelope. Upstream availability never becomes an empty success. Missing execution-quality inputs produce PARTIAL_DATA; fundamentally unavailable required datasets produce BLOCKED_DATA; implementation or invariant failures produce FAIL.