Capability register¶
This page is generated, and it is filtered
Every row is produced from the machine-readable evidence packets the frontend, backend and native documentation lanes each write. The build regenerates this page and fails if the committed copy no longer matches its inputs, so the register cannot drift away from the evidence.
It is not every claim in those packets. An evidence packet is private working material and legitimately holds implementation detail that should not be published. Each claim therefore carries an explicit publication decision, and a claim with no decision recorded fails the build rather than being published or dropped silently.
198 claims are recorded across three lanes. 195 are cleared for publication and appear below. 3 are withheld: they describe implementation detail — guards, authentication mechanics, storage, scope semantics — whose subjects are withheld from this site pending review. Where a bounded, user-meaningful statement could still be made about a withheld claim, that reviewed wording is what appears here instead of the raw sentence.
Status and availability are the originating lane's own grading, not a marketing summary.
Two different questions¶
Status answers how well do we know this? Availability answers can
anyone use it, and where? They are recorded separately and deliberately never
merged, because the interesting cases are exactly the ones where they disagree.
A capability can be Verified and Unavailable at the same time: the code was
read at the pin, and the code refuses. Reading one badge as though it answered
both questions is how a deferred surface gets documented as a working one.
Provenance status¶
| Status | Claims |
|---|---|
| Verified | 170 |
| Production record | 4 |
| Private / test stage | 1 |
| Target contract | 3 |
| Upstream | 4 |
| ONIX extension | 6 |
| Retired | 3 |
| Quarantined | 1 |
| Unverified | 6 |
| Total | 198 |
Availability¶
| Availability | What it means | Claims |
|---|---|---|
| Implemented | Present and working at the reviewed pin on at least one node or profile. | 145 |
| Preview | Present but behind a flag, profile or preview gate; not general. | 6 |
| Planned | A declared target contract. Not current behaviour. | 3 |
| Unavailable | Deferred, refused or removed at the reviewed pin. | 28 |
| Private | Exists but is restricted to a private, internal or operator-only deployment. | 16 |
| Total | 198 |
Author confidence¶
| Confidence | Claims |
|---|---|
| High | 180 |
| Medium | 18 |
Status tokens are defined on the status model. A low
confidence grading is a legitimate outcome, not a defect; see
evidence and testing.
Frontend / product¶
64 claims, all cleared for publication.
| Claim | Status | Availability | Confidence | Page |
|---|---|---|---|---|
| The dashboard/workspace-v2 chart bridge (window.__chartMcp) exposes the charting library's own widget API for symbol/resolution/visible-range, plus a second closed 'onix' capability namespace (instrument search, resolution listing, a chart-state read, and indicator/study list/add/remove/set-inputs) that its own source describes as a fixed, typed method list with no free-form code execution and no open-ended method dispatch. | Verified | Private (dashboard, workspace-v2) | High | product/chart-mcp-bridge |
| On a private-operator deployment, the venue-connection automation bridge reaches the same account-selection, connection-console, and order-entry actions the visible Connections widget and Order Ticket widget already reach; every such write still crosses the same same-origin proxy documented in gateway-realtime.md, which refuses all mutating backend routes unless the host itself is configured private-operator. | Verified | Private (dashboard) | High | product/chart-mcp-bridge |
| The /lab and /workspace consoles install a separate, read-only chart bridge (src/components/chart-mcp-bridge.tsx) that reaches exactly the same six enumerated /bars query controls (instrument_id, bar_type, start, end, after_sequence, limit) those consoles' own filter form exposes; every reachable path ends in a GET and the gateway refuses any other HTTP method. | Verified | Private (lab, workspace) | High | product/chart-mcp-bridge |
| Beyond the chart, three further widget-scoped browser bridges install only while their own /dashboard widget is mounted (screener workspace, venue connections/order ticket, strategy workbench); each is documented in its own source as reaching exactly the capability set its handle interface declares, mirroring the same widget-parity rule the chart bridge documents, with no generic script-execution capability in any of them. | Verified | Private (dashboard) | High | product/chart-mcp-bridge |
| catalogBarTypeSuffix re-spells the chart-facing composite bar_type suffix into the catalog/backtest form; submitting the chart spelling to a real BacktestNode was measured to produce 0 iterations and 0 orders versus 1492/52 for the correct spelling. | Verified | Implemented (dashboard, workspace-v2) | High | product/chart-datafeed |
| createGatewayDatafeed implements TradingView's IBasicDataFeed entirely against the spine.v2 gateway surface via fetchV2/subscribeToV2Stream, with no invented instruments or prices. | Verified | Implemented (dashboard, workspace-v2) | High | product/chart-datafeed |
| A prior hardcoded ADVERTISED_DISPLAY_RESOLUTIONS constant offered resolutions ('3','120') the gateway does not publish, and is documented as no longer read by the datafeed itself. | Retired | Unavailable (dashboard, workspace-v2) | High | product/chart-datafeed |
| The dashboard price chart is the licensed TradingView Advanced Charts widget, hosted by OnixAdvancedChart against vendored assets under public/static/charting_library/. | Verified | Implemented (dashboard, workspace-v2) | High | product/chart-datafeed |
| lightweight-charts remains in use only on the older /lab and /workspace consoles (via EngineChart), not on the /dashboard Advanced Charts widget. | Verified | Implemented (lab, workspace) | Medium | product/chart-datafeed |
| getBars always answers TradingView's noData as false because the backend publishes no exhaustion/coverage signal distinguishing 'nothing exists' from 'not yet backfilled', per the code's own EXHAUSTION IS THE BACKEND'S ANSWER note. | Target contract | Planned (dashboard, workspace-v2) | High | product/chart-datafeed |
| v2BarToTvBar and provisionalBarToTvBar are documented as the only two functions in src/datafeed/** permitted to call Number(...), because TradingView's Bar type is a bag of IEEE-754 doubles. | Verified | Implemented (dashboard, workspace-v2) | High | product/chart-datafeed |
| subscribeBars constructs a provisional current candle from live trade ticks because spine.v2 publishes only official closed bars with no partial-bar field; the provisional bar is discarded the instant a matching closed bar arrives. | ONIX extension | Implemented (dashboard, workspace-v2) | High | product/chart-datafeed |
| The resolution menu offered by onReady and resolveSymbol is read at runtime from GET /v2/resolutions rather than hardcoded, and both call sites derive their roster from the same cached read. | Verified | Implemented (dashboard, workspace-v2) | High | product/chart-datafeed |
| The vendored contract-manifest.json declares schema_set.count 58 and schema_set.sha256 28fdebfb5b5a318455dacdff4375deb77237dc5a1d56ab26238cd27f59c2ec42, matching scripts/engine-pin.mjs's ENGINE_SCHEMA_SET_SHA256/ENGINE_SCHEMA_COUNT constants. | Verified | Implemented (development-pin) | High | product/gateway-realtime |
| scripts/engine-pin.mjs pins two separate immutable commit/tree pairs against onix-backend (accepted release vs. contract authority), both read exclusively via git show, never a mutable working tree. | Verified | Implemented (development-pin) | High | product/gateway-realtime |
| Chart widget selection flows both ways: a watchlist click calls setSymbol on the live widget, and TradingView's own header symbol search flows back into the shared dashboard selection via onSymbolChanged. | Verified | Implemented (dashboard) | High | product/dashboard-and-workspaces |
| ConnectionSelectionContext carries the backend's own environment string (paper/live/sandbox) verbatim rather than re-deriving it, per its module doc's statement that 'mode is a backend fact the UI must display conspicuously and must never compute.' | Verified | Implemented (dashboard) | High | product/dashboard-and-workspaces |
| /dashboard's layout-store falls back silently to DEFAULT_LAYOUT on an unknown or malformed stored value, explicitly because layout is UI preference, not required trading-domain data covered by the project's fail-visibly rule. | Verified | Implemented (dashboard) | High | product/dashboard-and-workspaces |
| The /dashboard widget registry is a plain in-memory Map populated by registerWidget() calls; DashboardApp (widgets.tsx) is the single composition point deciding the full roster and its order. | Verified | Implemented (dashboard) | High | product/dashboard-and-workspaces |
| DashboardSelectionContext carries instrumentId/barType/resolution as a dependency-free React context (plain useState), and resolution is the gateway's published resolution key, not a TradingView ResolutionString. | Verified | Implemented (dashboard) | High | product/dashboard-and-workspaces |
| DashboardShell implements sidebar/bottom-bar resize purely via plain pointer events (useResizeDrag), with no third-party drag library, plus keyboard arrow-key operation of the same handles. | Verified | Implemented (dashboard) | High | product/dashboard-and-workspaces |
| GET /v2/registry publishes seven distinct capability statuses (READY, DISABLED, UNSUPPORTED, UNAVAILABLE, UNKNOWN, WARMING, UNPUBLISHED), each documented as a genuinely different claim that must not be collapsed into another. | Verified | Implemented (all) | High | product/gateway-realtime |
| ONIX_DEPLOYMENT_MODE is resolved server-side only, never from a request/header/cookie, and any unset or unrecognised value fails closed to public-readonly rather than to the more permissive private-operator mode. | Verified | Implemented (all) | High | product/gateway-realtime |
| No user login, session, or account-management route/module was found under src/** at this pin; the only two-valued trust distinction found is the server-side deployment mode. | Unverified | Unavailable (all) | Medium | product/gateway-realtime |
| deployment-mode.ts states explicitly that no credential lives in that module: it resolves a two-valued label only, so there is no secret for a bundle, NEXT_PUBLIC_* variable, or JS-readable cookie to leak. | Verified | Implemented (all) | High | product/gateway-realtime |
| The same-origin proxy at /api/engine/[...path] holds no fixtures and no fallback path; if the backend gateway is down it produces a failure the UI renders as unavailable, and it must be impossible for this handler to make an absent engine look present. | Verified | Implemented (all) | High | product/gateway-realtime |
| withheldFromPublicEdge withholds a private-operator-only request pre-emptively, client-side, unless the host has POSITIVELY stated private-operator; a pending or public-readonly resolution both withhold, closing the window where an unanswered configuration route would let requests through. | Verified | Implemented (all) | High | product/gateway-realtime |
| The v1 SSE client deliberately does not use the browser's EventSource because it cannot set request headers and its automatic reconnect is unbounded and uncancellable; a manual fetch + ReadableStream reader is used instead, resuming via a ?cursor= query parameter for every connect. | Verified | Implemented (all) | High | product/gateway-realtime |
| spine.v2 bodies must declare version:'spine.v2', errors arrive as {version, error:{code,detail}}, and streams deliver named events (bar/quote/trade/heartbeat) with no resume cursor, distinct from the v1 surface's cursor-sequenced schema-tagged documents. | Verified | Implemented (all) | High | product/gateway-realtime |
| AGENTS.md states the frontend owns presentation/interaction/workspaces/datafeed-adaptation while the backend owns instruments, market data, aggregation, catalog storage, strategies, backtests, portfolio, risk, orders, execution and runtime lifecycle. | Verified | Implemented (all) | High | product/index |
| Alongside the two workspace shells (/dashboard, /workspace-v2), three older internal consoles exist and are reachable at this pin: /workspace, /lab, and /admin. | Verified | Implemented (workspace, lab, admin) | High | product/dashboard-and-workspaces |
| The Next.js service listens on port 3117 in both dev and start scripts, and AGENTS.md states it can run on DigitalOcean droplets, proxied to the backend gateway via server-only env vars. | Verified | Implemented (development-pin) | High | product/index |
| The app's own navigation component labels /dashboard as the primary product surface and /lab, /workspace, /admin as secondary internal consoles. | Verified | Implemented (all) | High | product/index |
| AGENTS.md explicitly instructs contributors not to add direct exchange connections, venue adapters, market-data aggregation, catalog storage, trading state, portfolio/risk logic or an execution engine to this repository. | Verified | Implemented (all) | High | product/index |
| At this pin the Next.js app router serves exactly six pages (/, /dashboard, /workspace, /workspace-v2, /lab, /admin) plus four API routes, with / redirecting to /dashboard. | Verified | Implemented (all) | High | product/index |
| The /dashboard runtime registers an Order Ticket widget (src/components/runtime/ticket.tsx) that submits/cancels orders via POST /v2/orders and POST /v2/orders/cancel, then follows the resulting command through GET /v2/commands/{command_id}; the visible submit control is disabled unless the deployment resolves to private-operator. | Verified | Private (dashboard) | High | product/dashboard-and-workspaces |
| The /dashboard Performance report widget (src/components/runtime/performance.tsx) always renders a not-published panel at this pin: no route exists for a standalone performance report outside of one backtest job's own reports/stats fields. | Verified | Unavailable (dashboard) | High | product/dashboard-and-workspaces |
| The /dashboard Portfolio widget (src/components/runtime/portfolio.tsx) renders the Nautilus portfolio document generically and its own comment states GET /v2/portfolio is unpublished on every gateway reachable at this pin, so the widget renders the neutral not-published state rather than live figures. | Verified | Unavailable (dashboard) | High | product/dashboard-and-workspaces |
| evaluateScreen in screen.ts is a pure, gateway-free function usable both by the screener workspace UI and the MCP bridge's applyScreen, evaluating an already-validated screen definition over rows passed in, never read from a store. | Verified | Implemented (dashboard) | High | product/screener |
| columns.ts builds one table column per declared feature OUTPUT (not per feature), keyed by outputKey(featureId, outputName), matching the exact key ScreenerRowDoc.values uses. | Verified | Implemented (dashboard) | High | product/screener |
| The screener gateway module records a read-only live probe confirming specific route shapes, e.g. /v2/screener/health returning both the spine.v2 envelope and a complete screener health document. | Verified | Implemented (dashboard) | Medium | product/screener |
| Screener column headers render the backend-declared output identifier verbatim; the registry declares no display label or unit, so nothing in the frontend invents an English name for a feature output. | Verified | Implemented (dashboard) | High | product/screener |
| POST /v2/screener/screen is relayed by the frontend transport with the caller's exact document unexamined, because the screener process itself owns the grammar of what it accepts. | Verified | Implemented (dashboard) | High | product/screener |
| The screener client reads GET /v2/screener/features|snapshot|health|observations, posts /v2/screener/screen, and subscribes to GET /v2/stream/screener, all through the shared fetchV2/postV2Command/subscribeToV2Stream transport. | Verified | Implemented (dashboard) | High | product/screener |
| validateDocument checks, in a fixed documented order, object-shape, schema-tag presence, whether the schema is vendored, whether the observed schema_id matches the caller's expectation, and whether the wire version is understood, before the AJV structural check runs; compiled validators are cached per schema_id. | Verified | Implemented (all) | High | product/client-state-and-cache |
| The Backtests runs store persists only the lightweight BacktestJobSummary roster to localStorage; full BacktestJobDetail and streamed log lines are never written to storage, and a corrupt roster is recoverable by re-merging from GET /v2/backtests. | Verified | Implemented (dashboard) | High | product/client-state-and-cache |
| package.json's dependencies and devDependencies at this pin contain no Redux, Zustand, Jotai, MobX, React Query, or SWR package. | Verified | Implemented (all) | High | product/client-state-and-cache |
| No module found at this pin writes a live trading fact (an order, a fill, a position, a bar) to localStorage; the only modules calling localStorage at all persist UI layout preference, saved screener screens/columns, or a lightweight backtest-job summary roster. | Unverified | Unavailable (dashboard, workspace-v2) | Medium | product/client-state-and-cache |
| loadResolutionContract caches one successful read per page load in a module-level promise, but a FAILED read is explicitly not memoized, so the next caller retries rather than the datafeed freezing on a transient failure. | Verified | Implemented (dashboard, workspace-v2) | High | product/client-state-and-cache |
| The supported (schema_id, schema_version) registry is read directly out of each vendored schema's own const-pinned tags rather than hand-maintained, because a prior hand-maintained table was already found to assert version 1 for every schema incorrectly. | Verified | Implemented (all) | High | product/client-state-and-cache |
| The tick store never calls a React setter directly from an SSE event; it mutates a private draft and schedules one flush per animation frame (falling back to a 16ms setTimeout), so a burst of ticks within one frame produces at most one React render. | Verified | Implemented (dashboard) | High | product/client-state-and-cache |
| The dashboard tick store is a plain module-level singleton read via useSyncExternalStore, explicitly chosen over a React context because a dashboard has exactly one of it regardless of reader count, replacing three widgets each formerly opening their own unfiltered ~820-instrument stream. | Verified | Implemented (dashboard) | High | product/client-state-and-cache |
| The capability-status table's claim of a 58-schema accepted contract is cross-checked against the same contract-manifest.json used in gateway-realtime.md, not restated independently. | Verified | Implemented (development-pin) | High | product/capability-status |
| The frontend's sandbox and backtest surfaces read the backend-published connection environment label (paper/live/sandbox) rather than computing or overriding it. | Quarantined | Unavailable (dashboard) | Medium | product/capability-status |
| The authoring registry consumer states a hard rule that it never hard-codes, bundles, or invents a Nautilus class/method name, completion item, or hover/diagnostic content, and that an empty symbols list renders as empty rather than a synthesized fallback. | Verified | Implemented (dashboard) | High | product/strategies-and-backtesting |
| The Strategy Studio editor is built on CodeMirror (@codemirror/state, @codemirror/lang-python, @codemirror/merge for revision diffing), not a proprietary or third-party IDE embed. | Verified | Implemented (dashboard) | High | product/strategies-and-backtesting |
| A finished backtest job's execution block (capital, currency, fee model, fill model, determinism/seed) is typed and rendered on BacktestJobDetail, i.e. readable after a run even though the same five fields cannot be chosen before one. | Verified | Implemented (dashboard) | High | product/strategies-and-backtesting |
| The backtest results widget renders no progress bar or ETA for a running job because BacktestJobEvent carries only STATE and LOG and the job document has no percentage, bar counter, or ETA field. | Verified | Implemented (dashboard) | High | product/strategies-and-backtesting |
| The backtest submit wire shape (StrategyBacktestSubmitSpec) accepts a single optional instrument_id, not an array, so a multi-instrument workbench run is submitted as N separate backend jobs batched client-side, never a synthesized combined-portfolio result. | Verified | Implemented (dashboard) | High | product/strategies-and-backtesting |
| The Strategy Sandbox widget is mounted only inside PrivateOperatorSurface, and its status poll being gated is what stops a public deployment's browser from ticking a private route every 3 seconds forever. | Verified | Private (dashboard) | High | product/strategies-and-backtesting |
| Initial capital, account currency, fee model, fill model and a deterministic seed have no field on the backtest submit wire shape at all; the UI renders them as explicitly inert rows citing docs/contract-requests/026, rather than silently sending or hiding them. | Target contract | Planned (dashboard) | High | product/strategies-and-backtesting |
| workspace-v2's BUILTIN_WIDGETS catalog is a compile-time frozen constant; there is no registerWidget() API, and backend capability data may only toggle an already-declared widget's availability, never contribute an import path or component. | Verified | Implemented (workspace-v2) | High | product/dashboard-and-workspaces |
| workspace-v2's layout-storage deliberately does NOT adopt /dashboard's silent fallback: a stored document that fails strict parseLayoutDoc, or exceeds a byte ceiling, is surfaced to the shell as a visible failure string. | Verified | Implemented (workspace-v2) | High | product/dashboard-and-workspaces |
| workspace-v2's BUILTIN_WIDGETS catalog holds exactly 9 widget types at this pin: chart, strategy-studio, strategy-manager, strategy-backtests, open-positions, closed-positions, open-orders, order-history, and dev-status; the chart and Strategy Studio are named in the module's comments as the surface's original 'proof widgets'. | Verified | Implemented (workspace-v2) | High | product/dashboard-and-workspaces |
Backend / platform¶
93 of 94 claims are published here; 1 are withheld pending disclosure review of their subject.
| Claim | Status | Availability | Confidence | Page |
|---|---|---|---|---|
| nautilus-trader 2.0.0rc3, source commit 648970ce64a304d93da0a29320cb6e19b905fa39, is locked in python/uv.lock. | Verified | Implemented (all) | High | backend/nautilus-boundary |
| ONIX maintains a private, source-auditable Linux build of NautilusTrader carrying one patch to the Hyperliquid adapter's subscription-acknowledgement (SubscriptionState) lifecycle, not publicly distributed; identity is verified via a chain of checks that fail closed when unauthorized. | Verified | Private (linux-x86_64-build, hyperliquid-adapter) | High | backend/nautilus-boundary |
| python/uv.lock resolves nautilus-trader from the public PyPI wheel on macOS/arm64 but from a separate, non-PyPI wheel path for Linux/x86_64. | Verified | Private (linux-x86_64-build) | High | backend/nautilus-boundary |
| ONIX registers multiple official Binance data-client instances for one product and shards instruments across them via first-class add_data_client(routing=)/client_id= parameters, to bound the venue's WebSocket resubscribe frame size; a time-boxed upstream search found no existing fix to adopt. | ONIX extension | Implemented (binance-profile) | High | backend/nautilus-boundary |
| Nautilus owns instruments, market data, aggregation, catalog primitives, clock, cache, portfolio, accounting, risk, orders, fills, positions, execution and runtime lifecycle; ONIX Python owns product composition, catalog workflows, strategies, screening, gateway API and MCP; ONIX Rust crates never link Nautilus. | Verified | Implemented (all) | High | backend/index |
| The ONIX Rust workspace declares zero Nautilus dependencies; Nautilus enters the build only as a Python wheel, per ADR 0001 (LGPL boundary argument). | Verified | Implemented (all) | High | backend/nautilus-boundary |
| The tracked production record's own evidence field cites an external production ledger file that is not tracked in this repository; this documentation effort did not read it, and no live host state was independently observed. | Production record | Implemented (core-spine-production-record) | High | backend/capability-status |
| Only the 1m resolution is durable (the catalog's own canonical bar type); 5m/15m/30m/1h/4h/1d are derived on read via Nautilus's composite bar-type mechanism, one shared table (spine.resolutions) used by both gateway and derivation engine. | Verified | Implemented (all) | High | backend/data/aggregation |
| A derived bar's close lands on Nautilus's own UTC calendar grid via TimeBarAggregator::get_time_bar_start, proven by the backend's own boundary-alignment tests, not asserted from documentation; calendar_aligned:true on GET /v2/resolutions reflects this. | Verified | Implemented (all) | High | backend/data/aggregation |
| The derivation layer withholds any derived bucket whose constituent window intersects an unresolved gap in the durable 1-minute series, rather than serving a value computed from a partial input set. | Verified | Implemented (all) | High | backend/data/aggregation |
| The node runs time_bars_build_with_no_updates=False node-wide (Option A, INTERNAL_1M_DATA_ENGINE_OVERRIDES in spine.internal_1m_collector) -- the opposite of the pinned wheel's own True default. python/tests/test_internal_1m_replay_gates.py::test_b4_option_a_also_makes_the_one_second_tier_sparse proves a quiet second produces no 1-second INTERNAL bar at all (0 < len(seconds) <= len(_ALL_TICKS) + 1, no duplicate timestamps) through a real BacktestEngine, not a synthetic flat carry-forward bar. | Verified | Implemented (all) | High | backend/data/aggregation |
| A non-durable second-resolution tier is aggregated inside Nautilus from the live trade stream (not a second venue subscription) and is bounded to a configurable prefix of the universe (default first 25 instruments). | Verified | Implemented (all) | High | backend/data/aggregation |
| next_to_start() returns a start hint so an already-READY series requests only the gap above its own newest close on restart, never the full window again. | Verified | Implemented (all) | High | backend/data/catalog |
| Because on_historical_bars carries no request id, HydrationManager correlates an empty response to its instrument by elimination against the small set of in-flight requests, using catalog rows as ground truth; a large in-flight set was measured to make correlation ambiguous and cost hydration time. | Verified | Implemented (all) | Medium | backend/data/catalog |
| HydrationManager's internal state machine is EMPTY -> HYDRATING -> READY | NO_HISTORY | RETRY_WAIT | FAILED; the wire GET /v2/hydration status vocabulary is the four-value EMPTY|HYDRATING|READY|FAILED. | Verified | Implemented (all) | High | backend/data/catalog |
| Durable retention is instruments plus at most the latest 5,000 closed 1-minute bars per instrument; other resolutions and quotes/trades are never durably stored. | Verified | Implemented (all) | High | backend/data/catalog |
| CatalogStore is a thin typed facade over nautilus_trader.persistence.ParquetDataCatalog with no custom Parquet layout, compaction, sharding, or archival logic. | Verified | Implemented (all) | High | backend/data/catalog |
| One ParquetDataCatalog mechanism serves two physically separate roots -- EXTERNAL (venue klines, history/backfill/repair only) and INTERNAL (live-derived, TimeBarAggregator over TradeTicks) -- never relabelled or cross-filled. Both are consolidated via the same pinned consolidate_catalog/consolidate_data(_by_period) API (1-day default period) but on separate schedules. Writers to the INTERNAL root are admission-gated on min_free_inodes/max_files floors (a later revision adds min_free_bytes), with census/watermark/error telemetry recorded every cycle, following a 2026-08-24 production outage that exhausted 4,915,200/4,915,200 inodes on a 149 GiB volume roughly half-empty by bytes. deploy/retained-ingestion.json is the stated production instrument-demand authority for both roots; a catalog-writing service must refuse to start if its expected volume is not mounted and writable. | Verified | Implemented (all) | High | backend/data/catalog |
| Quotes, trades and per-second bars flow live but are never durably stored; only instruments and the rolling 1-minute series persist. | Verified | Implemented (all) | High | backend/data/index |
| CoverageLedger's vocabulary is ACTIVE/INACTIVE: |
Verified | Implemented (all) | High | backend/data/ingestion |
| The development-pin deploy/retained-ingestion.json is manifest_version 8, epoch 1, covering Bybit (2 active + 3 historically retired instruments) and Hyperliquid (3 active instruments) -- a different, later manifest than the production record's mv5. | Verified | Preview (development-pin) | High | backend/data/ingestion |
| spine.actor.MarketSpineActor implements on_mark_price, on_index_price, on_funding_rate, on_option_greeks, and on_instrument_status callbacks (alongside on_bar), each converting via a dedicated spine.wire. |
Verified | Implemented (all) | High | backend/data/ingestion |
| CUDISUSDT-SPOT.BYBIT is named in the production record's mv5-epoch1 roster notes, yet the development-pin's mv8 manifest already records that same instrument as retired at manifest_version 6. | Verified | Implemented (core-spine-production-record, development-pin) | High | backend/data/ingestion |
| The INTERNAL 1-minute collector subscribes to one INTERNAL 1-minute BarType per instrument; Nautilus's own DataEngine/TimeBarAggregator performs all aggregation; the module constructs no Bar and re-stamps nothing; a minute with no trades produces no bar, live and persisted alike. | Verified | Implemented (all) | High | backend/data/ingestion |
| Nautilus's engine performs no bar-level deduplication; two bars with identical timestamps are both delivered in insertion order. | Upstream | Implemented (all) | Medium | backend/data/ingestion |
| The tracked CURRENT_PRODUCTION record states the deployed retained-ingestion manifest is mv5-epoch1, and names it as the production instrument-demand authority; this is a production-record claim, not an independent observation. | Production record | Implemented (core-spine-production-record) | High | backend/data/ingestion |
| series_coverage.retention_state is one of retained/unretained/unmanaged; history_terminal = exhausted OR retention_state == unretained. | Verified | Implemented (all) | High | backend/data/ingestion |
| internal_bars is the one channel marked sparse_ok:true in coverage, because a minute with no trades legitimately produces no INTERNAL-aggregated bar. | Verified | Implemented (all) | High | backend/data/ingestion |
| The generated contract manifest at functional source commit f80bc316ca01e9ea68a77ad6fd2ca0efe89ee7ba names 58 schemas with schema-set sha256 28fdebfb5b5a318455dacdff4375deb77237dc5a1d56ab26238cd27f59c2ec42. | Verified | Implemented (all) | High | backend/gateway-schemas |
| Canonical JSON used for identity hashing has sorted keys, no insignificant whitespace, no floats anywhere (decimals/nanosecond timestamps are strings), and exact documented escaping rules (lowercase \uXXXX, non-ASCII emitted raw, astral chars as 4-byte UTF-8, solidus not escaped, U+2028/U+2029 not escaped). | Verified | Implemented (all) | High | backend/gateway-schemas |
| onix.capability_registry is generated directly from the real gateway_v2 route tables and the real MCP tool table (never hand-authored), with a test walking both live tables to fail loudly on drift; availability vocabulary is READY/UNSUPPORTED/WARMING/DISABLED/UNAVAILABLE/UNKNOWN/UNPUBLISHED. | Verified | Implemented (all) | High | backend/gateway-schemas |
| A backtest revision naming multiple instruments across different venues builds one Nautilus venue configuration per distinct venue, all inside a single BacktestNode -- a three-symbol, mixed-venue revision receives all three in one run, not three separate runs. Any one-instrument-per-job constraint observed elsewhere in the product is an override imposed by a specific caller (e.g. a frontend route), not a backend demand-seal or BacktestNode limitation. | Verified | Implemented (gateway-backtest-path) | High | backend/trading/backtesting |
_require_sealed_spec computes unknown = sorted(set(spec) - allowed) against _BACKTEST_SPEC_KEYS (9 named keys) / _SANDBOX_START_SPEC_KEYS (3 named keys) and raises ValueError(f"{route} does not accept {unknown}; allowed keys are {sorted(allowed)}") when any unknown key is present -- an unrecognized key in a POST /v2/backtests or POST /v2/sandbox/start body is refused with a 400, never silently dropped or ignored. |
Verified | Implemented (all) | High | backend/trading/backtesting |
| AST-parsed (not substring-counted) at the pin: TOOLS contains 81 ToolSpec entries, of which 16 have read_only=False. GATED_TOOLS contains exactly one entry (ibkr_cancel_order, origin="ibkr", read_only=False), registered only when the process starts with ONIX_MCP_ALLOW_CONTROL=1 (default off). Maximum across both sets: 82 tools, 17 mutating. The default advertised set is 81 tools, 16 mutating. | Verified | Implemented (all) | High | backend/mcp |
Every MCP tool argument except one is validated against a closed enum or a bounded, regex/range-checked scalar before use, stated as an explicit security requirement: "a caller must not be able to name a URL." The one exception is config (backtest/sandbox submission): _MAX_CONFIG_BYTES = 65_536 and _validate_config_field requires a JSON object that serializes to at most that many bytes -- a type-and-size ceiling, not a closed set of values. |
Verified | Implemented (all) | High | backend/mcp |
| GATED_TOOLS contains exactly one ToolSpec, ibkr_cancel_order (read_only=False, origin="ibkr"), registered only when the MCP process is started with ONIX_MCP_ALLOW_CONTROL=1 (default off). A separate --tool-profile operator-control flag narrows advertisement to the frozen OPERATOR_CONTROL_TOOL_NAMES subset and is mutually exclusive with allow_control; the default profile advertises exactly TOOLS (81 tools). | Verified | Preview (ibkr-node) | High | backend/mcp |
| onix_engine.mcp.server wires the frozen tool table to a stdio-only MCP server. The module's own docstring states this directly: 'Transport: stdio only. This module never constructs an HTTP/SSE transport for the MCP side -- there is no streamable_http_app()/uvicorn call anywhere in this file.' The mcp SDK dependency transitively pulls in starlette/uvicorn/sse-starlette (one package serving every MCP transport), but nothing in this codebase imports or runs that HTTP surface. | Verified | Implemented (all) | High | backend/mcp |
| Fifteen MCP tools call the v1 fixture/runtime gateway rather than spine.gateway_v2: get_liveness, get_readiness, get_engine_status, get_venue_capability_matrix, get_run_receipt, list_instruments, get_backtest_result, list_bars, list_signals, list_retirements, list_screener_rows, list_chart_markers, get_catalog_summary, list_schemas, get_schema. python/tests/test_capability_registry.py checks this named set and capability_registry.unmapped_tools() reports it. Several /v2 routes (health, screener snapshot, one coverage variant, order submission, two selection routes) have no MCP tool yet. | Verified | Implemented (all) | High | backend/mcp |
| This documentation's search for a second private Nautilus patch beyond the named Hyperliquid subscription-acknowledgement patch was bounded to a text search of the pinned repository tree at commit efa38e04e2db37a444e9f17100323c2ad4b83647 for patch/vendor/private-wheel naming conventions -- not an audit of the wheel's own compiled bytes, and not a search of any system outside this repository. "Never forked" is corrected to: official base plus one surfaced private Linux patch, no long-lived public fork -- not a claim the upstream wheel is globally unmodified (the macOS/arm64 development wheel is the unmodified public artifact; the Linux/x86_64 deployment wheel carries the named private patch). | Verified | Private (linux-x86_64-build) | High | backend/nautilus-boundary |
| LiveNode Cache save/load (with_load_state/with_save_state) is reachable and does not raise, but at this pin Cache has no has_backing accessor and CacheConfig has no database/backing field, so it can only ever persist/restore nothing -- classified UPSTREAM_PYTHON_BINDING_UNAVAILABLE. | Verified | Unavailable (all) | Medium | backend/runtime/cache-message-bus |
| deploy/activation.json's own comment states an enabled roster entry 'controls artifact composition only and is never authority to deploy production'. | Verified | Implemented (development-pin) | High | backend/runtime/index |
| onix.engine_status transitions are STARTING/RUNNING/CHECKPOINTED/COMPLETED/FAILED with an explicit allowed-transition table; emitted by the producer and served verbatim, never synthesized from file existence. | Verified | Implemented (all) | High | backend/runtime/index |
| Nautilus's Rust event store (capture/seal/replay) is real and wired into the kernel lifecycle in Rust, but LiveNodeBuilder has no with_event_store method on its Python surface at this pin -- a total, not partial, absence. | Verified | Unavailable (all) | Medium | backend/runtime/cache-message-bus |
| GET /health is transport liveness only; GET /readiness reports condition/freshness (lifecycle state plus per-authority gap/duplicate/out-of-order counters from the run receipt, read verbatim) and is served only in RUNTIME mode. | Verified | Implemented (core-spine-v1-gateway) | High | backend/runtime/index |
| A standalone MessageBus proves real end-to-end publish/subscribe for the in-process bus (dict round-trip); has_backing is False by default and under an explicit default MessageBusConfig(); external (Redis) backing is unreachable for the same reason cache backing is. | Verified | Implemented (all) | Medium | backend/runtime/cache-message-bus |
| The market spine node runs with default data/portfolio/risk engine configuration and registers no exec/risk client at all; the module composing it states directly 'the market spine node runs no execution engine at all'. | Verified | Implemented (all) | High | backend/runtime/index |
| Because external MessageBus backing is unreachable at this pin (CacheConfig/MessageBusConfig have no field for a Redis-backed config object; see the cache/message-bus probes), no Redis-backed or otherwise externally-backed cross-process message-bus topology is wired up, reachable, or half-built anywhere in this repository at this pin. Cross-process fanout is instead plain HTTP Server-Sent Events over spine.state.SpineState's in-process bounded-queue broadcast. | Verified | Unavailable (all) | Medium | backend/runtime/cache-message-bus |
| A committed systemd-unit inventory (deploy/testing/units/*.service) names one unit per venue integration (onix-bybit, onix-binance, onix-hyperliquid), the public gateway (onix-gateway), the operator gateway (onix-operator-gateway), the screener (onix-screener), and the IBKR preview/display stack (ibkr-gateway, ibkr-novnc, ibkr-x11vnc, ibkr-xvfb, onix-ibkr-preview). Restart-safety for hydration scheduling state and closed-period consolidation watermarks is proven by python/tests/test_runtime_lifecycle.py and python/tests/test_internal_lifecycle.py, not asserted from prose. | Verified | Implemented (all) | Medium | backend/trading/execution-runtime |
| The tracked CURRENT_PRODUCTION record names five production units (Bybit spine, public gateway, operator gateway, screener, loopback frontend), all Bybit-only, with Nautilus 2.0.0rc3 and live 1m closes sourced from INTERNAL TimeBarAggregator bars over trade ticks (external klines used for history/backfill/repair only). Live host state was never independently observed. | Production record | Implemented (core-spine-production-record) | High | backend/runtime/index |
| Each spine process registers one Nautilus DataActor (spine.actor.MarketSpineActor) via add_actor_from_config (the only released custom-actor registration path). It shares one thread-safe spine.state.SpineState with the gateway threads -- the actor records observations, the gateway reads snapshots and subscribes to the SSE fanout -- and computes nothing itself ("no detector logic, no computed fields", per its own docstring). The SSE fanout (onix_engine.gateway_sse) replays the same schema-valid DTO bytes the equivalent GET route serves, carries a run-scoped sequence cursor per event, and emits an explicit event: resync when a requested cursor can no longer be satisfied. | Verified | Implemented (all) | High | backend/runtime/index |
| nautilus-trader 2.0.0rc3 removed LiveNode.start() and LiveNode.poll(); the only official run surfaces are the blocking run() and the coroutine run_async(). | Upstream | Implemented (all) | High | backend/runtime/index |
| At rc2, RedisCacheConfig/PostgresCacheConfig/RedisMessageBusConfig raised TypeError on construction; at rc3, all three construct successfully with zero-arg defaults, but CacheConfig still has no field to accept one -- so external backing remains unreachable end to end. | Verified | Unavailable (all) | Medium | backend/runtime/cache-message-bus |
| ONIX drives the synchronous run() rather than run_async() because a measured GIL/native-waker lock-order inversion in the pinned wheel's run_async() driver stalled multi-client connects (5/20 single-product, 10/10 four-product) while run() was 20/20 clean on the identical composition. | Verified | Implemented (all) | Medium | backend/runtime/index |
| The v1 gateway (onix_engine.gateway) is retained only because some MCP tools still read through its routes; the governed production surface is spine.gateway_v2 / gateway_multi. | Verified | Implemented (all) | High | backend/runtime/index |
| A feature value that is not yet warm or whose input is unavailable reports ABSENT with a reason; it never reports a zero, null, or silently-omitted key; a missing key means 'not in the registry', ABSENT means 'registered but currently untrustworthy'. | Verified | Implemented (all) | High | backend/screener |
| A stale statement in the screener's Python confluence module's own docstring says the row-producing projection emits only the 1m resolution, so every derived-timeframe confluence input is permanently ABSENT. This is contradicted at this pin by projection.py's RESOLUTIONS_PRODUCED (built from the full seven-key spine.resolutions.RESOLUTIONS table) and by python/tests/test_screener_bridge.py's own executable test, whose comment states it "pins the CONFLUENCE DEFECT closed" and asserts RESOLUTIONS_PRODUCED == ("1m","5m","15m","30m","1h","4h","1d"). A derived timeframe still reports ABSENT (and votes neutral) only until its own series accumulates enough closed bars to warm up its indicators -- ordinary warmup behavior, not the structural defect the docstring describes. This documentation has no live measurement of a fully-warmed multi-timeframe confluence score at this pin. | Unverified | Implemented (all) | Medium | backend/screener |
| feature_row_delta distinguishes a key that left the registry entirely (removal) from a key whose value became Absent (registered but untrustworthy, column stays on screen) -- conflating them would either leave a stale value displayed forever or blank a column merely warming up. | Verified | Implemented (all) | High | backend/screener |
| A screener that is not running reports process_state STOPPED with a real last_error (gateway-synthesized document), distinguishing 'not running' from 'running, nothing matched'; connection accounting is still reported as honest all-zeroes rather than omitted, and egress with no seam reports explicit null rather than false zeroes. | Verified | Implemented (all) | High | backend/screener |
| onix_engine.screener.projection.RESOLUTIONS_PRODUCED is built from tuple(spine.resolutions.RESOLUTIONS) -- all seven chart resolutions (1m native, 5m/15m/30m/1h/4h/1d folded from DERIVED_BAR egress frames the Rust runtime emits back over the ingest socket via screener.bridge). This is proven by python/tests/test_screener_bridge.py::test_every_contract_resolution_is_produced_not_only_the_base_one, whose own docstring states it pins the CONFLUENCE DEFECT closed. | Verified | Implemented (all) | High | backend/screener |
| Twenty strategy templates exist as source files under python/src/onix_engine/studio/templates/ at the pin. | Verified | Implemented (all) | High | backend/trading/strategy-authoring |
| onix_engine.studio.admission is the one door every path that turns a revision into a running child goes through, independently re-deriving ids, file set/hashes, engine pin, content identity, canonical demand and digest binding before SEALED+verified+promotable is required. | Verified | Implemented (all) | High | backend/trading/strategy-authoring |
| ADR 0003 explicitly places LLM/generated-strategy execution out of scope and records that no partial sandbox was built for it because 'a partial sandbox is worse than none'; this repository ships the description, not an implementation. | Verified | Unavailable (all) | High | backend/trading/strategy-authoring |
| A backtest builds a real, catalog-fed nautilus_trader.backtest.BacktestNode; BacktestDataConfig against the spine's own ParquetDataCatalog root is the official v2 data-loading path, verified directly against the installed wheel's stubs and by a real run. | Verified | Implemented (gateway-backtest-path) | High | backend/trading/backtesting |
| At this pin, BacktestNode streams lazily from the catalog only for a run built from exactly one BacktestDataConfig; otherwise it materializes every selected row of every config into memory, and which shape a run took is recorded, not implicit. | Verified | Implemented (gateway-backtest-path) | High | backend/trading/backtesting |
| POST /v2/backtests accepts an optional run_mode and chunk_size alongside strategy/revision/config/instrument/window fields. | Verified | Implemented (gateway-backtest-path) | High | backend/trading/backtesting |
| Every value written to a backtest job's state is read verbatim off official Nautilus objects (BacktestResult, Cache.orders()/positions(), Position.events(), Position.unrealized_pnl(), Portfolio.account()) -- no ONIX computation of any statistic. | Verified | Implemented (gateway-backtest-path) | High | backend/trading/backtesting |
| A revision's identity includes its data demand (demand_seal: SEALED vs DEMAND_UNSEALED); DEMAND_UNSEALED revisions are readable/validatable but refused for backtest/sandbox/study/promotion/holdout by the named code DEMAND_UNSEALED. | Verified | Implemented (all) | High | backend/trading/strategy-authoring |
| The reviewed market-data runtime includes an additional runtime check intended to prevent access to execution credentials. | ONIX extension | Implemented (all) | High | backend/trading/execution-runtime |
| The execution-safety boundary is a source-level control with documented limitations; it is not represented as a language-level sandbox or an independent external security audit. | Verified | Implemented (all) | High | backend/trading/execution-runtime |
| The reviewed market-data runtime refuses real execution-client registration while leaving simulated execution as a separately governed capability. | ONIX extension | Implemented (all) | High | backend/trading/execution-runtime |
| ExecutionEnvironment is a declared wire vocabulary of BACKTEST, SANDBOX, PAPER, LIVE; the existence of the LIVE value is a schema declaration, not evidence of an active LIVE-tagged execution path. | Target contract | Planned (all) | High | backend/trading/execution-runtime |
| On the IBKR node, GET /v2/account, /v2/accounts, /v2/portfolio, /v2/orders, /v2/fills, and /v2/positions are READY: they are served by the same shared gateway_v2 handlers every other node uses, backed by a real execution-projection (ibkr.execution.ExecutionProjector) that reads the official Nautilus IBKR execution client's captured cache/portfolio state. Unconfigured or unconnected states are reported honestly by name (execution_ready: false, reason ACCOUNT_NOT_CONFIGURED or EXEC_CLIENT_NOT_CONNECTED), never masked as empty-but-successful. | Verified | Implemented (ibkr-node) | High | backend/trading/portfolio-risk |
| GET /v2/account, /v2/accounts, /v2/portfolio, /v2/orders, /v2/fills, and /v2/positions all belong to onix_engine.spine.deferred.DEFERRED_OPERATIONS and answer HTTP 501 (capability.status "UNAVAILABLE", reason "DEFERRED_PAPER_PRODUCT") on the core spine and the Binance node. The previous behavior fabricated success instead: /v2/portfolio returned 200 with a zeroed portfolio and /v2/orders, /v2/fills, /v2/positions returned 200 [], while the capability registry reported all of them READY. | Verified | Unavailable (core-spine, binance-node) | High | backend/trading/portfolio-risk |
| ONIX's ibkr package contains genuine real-broker execution-projection code (only produces data with a configured account_id and connected exec client; unconfigured/unconnected states reported honestly by named reason). This capability is disabled in deploy/activation.json (ibkr.enabled:false) and absent from the tracked production record. | Private / test stage | Preview (ibkr-node) | High | backend/trading/execution-runtime |
| No process in the currently deployed or currently developed ONIX fleet registers a real venue execution client; this is structural (spine node composition + PublicDataNodeBuilder guard), not merely conventional. | Verified | Implemented (all) | High | backend/trading/index |
| No TypeScript-based strategy compile/execution/isolation runtime was found anywhere in this backend repository at the pin (searched docs/, python/src/onix_engine/studio/, python/src/onix_engine/workbench/** for TypeScript/deno/vm2/isolated-vm/abandoned-runtime terminology). | Unverified | Unavailable (all) | Medium | backend/trading/strategy-authoring |
| Nautilus computes position PnL in f64 (IEEE-754), then stores/transports the result as an exact decimal at the account currency's precision; Onix-owned arithmetic is fixed-point end to end with float arithmetic denied at lint level; Nautilus-derived values are exact as transported, not as computed. | Upstream | Implemented (all) | High | backend/trading/portfolio-risk |
| A previously-accepted raw ImportableStrategyConfig submission body (selected by absence of strategy_id, allowing arbitrary module:ClassName execution) has been removed from both POST /v2/backtests and POST /v2/sandbox/start; only a sealed {strategy_id, revision_id} pair resolves into executable strategy code. The MCP tools that published the raw shape were removed too. | Retired | Unavailable (all) | High | backend/trading/strategy-authoring |
| requires_paper is true only for the two order-mutation operations (POST /v2/orders, POST /v2/orders/cancel), stated as 'under this campaign's own discipline, exercised only in paper/sandbox mode'; requires_confirmation is true for the same two, and is the only pair with an external consequential side effect in the registry. | Verified | Implemented (all) | High | backend/trading/execution-runtime |
| result_hash is computed over the canonical result document with the result_hash field itself blanked to an all-zero 64-char digest at its normal sorted position, not omitted -- a documented, deliberate identity rule. | Verified | Implemented (all) | High | backend/trading/backtesting |
| revision_id IS the revision's content_hash (64 hex); saving identical content twice is idempotently the same revision; a published revision's files are never rewritten. | Verified | Implemented (all) | High | backend/trading/strategy-authoring |
| SpineService.sandbox_start/sandbox_stop/sandbox_status each raise a typed deferred refusal (onix_engine.spine.deferred.deferred("spine.sandbox.start"/"...stop"/"...status")) unconditionally, before any spec is read. POST /v2/sandbox/start, POST /v2/sandbox/stop, and GET /v2/sandbox/status answer HTTP 501 with capability.status "UNAVAILABLE", reason "DEFERRED_PAPER_PRODUCT" on the core spine and the Binance node. On the IBKR node the same three answer HTTP 404 NOT_SUPPORTED_ON_THIS_NODE ("UNSUPPORTED") because that node has no backtest-job store or simulated-execution concept at all. | Verified | Unavailable (core-spine, binance-node) | High | backend/trading/execution-runtime |
| Validation runs in a child-process boundary against the installed pin; editor-authored code is never imported into the market-spine process. | Verified | Implemented (all) | High | backend/trading/strategy-authoring |
| A local, single-user offline workbench CLI (distinct from the POST /v2/backtests gateway path) computes a content-addressed run_id_hex from engine identity, strategy id, config hash and fixture hash, and python/tests/test_workbench_rerun.py proves byte-identical canonical evidence bytes across a fresh-process rerun of the same scaffolded project. This proof is scoped to the workbench path only, not to jobs submitted through the gateway. | Verified | Implemented (workbench-cli) | High | backend/trading/backtesting |
| venues.registry derives 19 official Nautilus integration ids by reflection over the pinned wheel's nautilus_trader.adapters package, classified VENUE/DATA_PROVIDER/SIMULATED_EXECUTION. | Upstream | Implemented (all) | High | backend/venues/index |
| deploy/activation.json (development pin) enables Bybit (gateway core), Hyperliquid (ingest-only, execution explicitly disabled), and Binance (ingest-only, operator-boundary-gated); IBKR is enabled:false with a preview-only bundled unit. | Verified | Preview (development-pin) | High | backend/venues/index |
| Of the four venues this repository activates in any roster, this documentation found dedicated conformance/integration test files by name at the pin for all four: Bybit (test_bybit_adapter_authority.py and 2 others), Binance (9 files), Hyperliquid (5 files), Interactive Brokers (12 files). Every other upstream-shipped integration (Betfair, Bitmex, Blockchain, Coinbase, Databento, Deribit, Derive, dYdX, Kraken, Lighter, OKX, Polymarket, Tardis, Architect AX) has an ONIX profile source file but no dedicated conformance test suite found in this repository -- configured, not tested. | Verified | Implemented (bybit, binance, hyperliquid, ibkr-node) | Medium | backend/venues/index |
| onix.instrument_ref's instrument_id is the Nautilus canonical {raw_symbol}.{venue} string; the schema itself warns consumers to read venue/raw_symbol as fields rather than splitting on '.'. | Verified | Implemented (all) | High | backend/venues/instrument-identity |
| Venue onboarding should normally be declarative profile and registry work followed by conformance; if a venue needs a gateway/frontend/shared-host change, the correct response is to find the missing common seam, not add a venue-specific bypass. | Verified | Implemented (all) | High | backend/venues/onboarding |
| The tracked CURRENT_PRODUCTION record's five production units are all Bybit-only; no Hyperliquid or Binance unit is among them. | Production record | Implemented (core-spine-production-record) | High | backend/venues/index |
| IntegrationProfile is the one typed seam between the venue-agnostic spine runtime and one pinned adapter integration; constructing one imports no adapter module and owns no runtime state. | ONIX extension | Implemented (all) | High | backend/venues/index |
| venues.registry classifies exactly one of the 19 reflected upstream integrations, "sandbox", as kind SIMULATED_EXECUTION (an execution factory only, no data factory) -- Nautilus's own simulated-execution adapter, not a real venue profile. The other 18 are VENUE or DATA_PROVIDER integrations against a real exchange or data source. Counting "19 upstream venue integrations" without this distinction overstates real-venue breadth by one. | Verified | Implemented (all) | High | backend/venues/index |
| Instrument-to-shard assignment for a large universe uses a stable SHA-256 prefix of the instrument id, deliberately never Python's per-process salted hash(). | ONIX extension | Implemented (all) | High | backend/venues/instrument-identity |
Native clients and MCP¶
38 of 40 claims are published here; 2 are withheld pending disclosure review of their subject.
| Claim | Status | Availability | Confidence | Page |
|---|---|---|---|---|
| The ONIX-iOS repository's own source-baseline receipt states it was created 2026-08-19 by cloning a local, differently-branded multi-platform repository (no object sharing), then replacing the working tree with a fresh iOS-only project; it records an upstream compile defect that was deliberately not imported. | Verified | Private (ios-candidate-a) | High | evidence/native/ios-canonical-source-uncertainty.md |
| At Candidate A, the Release-build auth provider always reports an 'unavailable' identity state and never establishes or stores a session; a DEBUG-only synthetic session type is explicitly labeled as not real ONIX identity and is compiled out of Release. | Verified | Unavailable (ios-candidate-a) | High | native/ios |
| Candidate B's biometric privacy gate is documented in its own source as explicitly not an account-authentication implementation: it never sees or stores a username, password, token, or cookie, and can be dismissed by the device-owner fallback without authenticating an account. | Verified | Private (ios-candidate-b) | High | native/ios |
| iOS Candidate A (commit 9ce6595c, tree bdc3f2c6) has marketing version 0.1.0, build 1, bundle ids ai.onixlab.onix.ios / ai.onixlab.onix.ios.dev, iOS deployment target 17.0. | Verified | Private (ios-candidate-a) | High | native/ios |
| iOS Candidate B (commit 85cbdf09, tree fa9f9699) has marketing version 0.1.1, build 3, same bundle ids as Candidate A, and adds a biometric privacy lock plus other UI not present in Candidate A. | Verified | Private (ios-candidate-b) | High | native/ios |
| The ONIX-iOS repository has no ONIX-owned remote. Its only configured remote points at a local filesystem path with push disabled. | Verified | Unavailable (ios-candidate) | High | native/ios |
| Native Swift code in the iOS shell never talks to the backend, an exchange, or a broker directly; every API call the loaded page makes goes through that page's own same-origin proxy, entirely inside the WebView. | Verified | Private (ios-candidate-a, ios-candidate-b) | High | native/ios |
| This repository's own platform matrix explicitly classifies an on-device MCP server as out of scope for iOS, describing the MCP server as desktop-only with no iOS analog to build. | Verified | Unavailable (ios-candidate) | High | native/ios |
| This repository's own platform matrix explicitly excludes native order/position/portfolio surfaces from the iOS shell scope: fail-closed means these screens are simply absent, not stubbed. | Verified | Unavailable (ios-candidate) | High | native/support-boundary |
| Both iOS candidates implement a single, constrained WKWebView shell whose navigation policy allows only same-origin http(s), the WebView's own about:blank, and same-origin blob: child frames, refusing every other scheme outright. | Verified | Private (ios-candidate-a, ios-candidate-b) | High | native/ios |
| Candidate B's local commit history includes a commit titled 'Prepare ONIX iOS shell for TestFlight', consistent with an invite-only TestFlight distribution channel rather than public release. | Verified | Preview (ios-candidate-b) | High | native/ios |
| The local MCP tool registry's browser-bridge contracts are verified in source comments against frontend commit dd17521d (short form), which is recorded elsewhere in this documentation set's own provenance as an ancestor of the frontend commit 99f49dae this documentation set otherwise treats as current, and therefore requires revalidation. | Unverified | Implemented (macos-client) | High | native/macos |
| ONIX macOS build number (CURRENT_PROJECT_VERSION) is 55 at the reviewed pin. | Verified | Implemented (macos-client) | High | native/macos |
| ONIX macOS app bundle identifier is ai.onixlab.onix.macos.dev at the reviewed pin (a dev-suffixed identifier; no separate non-dev macOS bundle id was found in this project file). | Verified | Implemented (macos-client) | High | native/macos |
| A GitHub Actions workflow in the macOS repository builds a legacy iOS scheme against the iOS 26 SDK and is manually (workflow_dispatch) triggered pending GitHub-hosted runner support for that SDK. | Verified | Implemented (macos-client) | High | native/support-boundary |
| ONIX macOS product target's MACOSX_DEPLOYMENT_TARGET is 14.0. | Verified | Implemented (macos-client) | High | native/macos |
| The macOS app runs under App Sandbox with only network.client and network.server entitlements, and deliberately omits an associated-domains entitlement. | Verified | Implemented (macos-client) | High | native/macos |
| A source comment in the reviewed MCP tool registry states the predecessor codebase's registry advertised 82 tools, most of which could not function against ONIX because their backend contracts do not exist in this product. | Unverified | Unavailable (macos-client) | Medium | mcp/macos-host |
| Every request to the local MCP host must be authenticated with a credential issued from inside the running app; there is no anonymous or unauthenticated path to any tool. | Verified | Implemented (macos-client, local-host-default-scopes) | High | mcp/macos-host |
| Default enabled MCP scopes are read, app-control, draft, and backtest; the diagnostics scope is excluded from the default set. | Verified | Implemented (local-host-default-scopes) | High | mcp/safety-and-scope |
| An additional diagnostics capability exists for support use. It is disabled by default and is outside the local host's supported, default-scope boundary; this documentation does not describe what it exposes or how it can be enabled. | Verified | Preview (local-host-diagnostics-scope) | High | mcp/safety-and-scope |
| The native app does not itself make outbound HTTP requests to the backend; every backend request the app is involved in is the loaded web page's own same-origin request, made inside the WebView. | Verified | Unavailable (macos-client) | High | mcp/macos-host |
| The local MCP host includes an additional safeguard beneath the tool registry that rejects requests aimed at money-moving or account-mutating paths, independent of which tool made the request. | Verified | Implemented (local-host-default-scopes) | High | mcp/safety-and-scope |
| Order placement and order cancellation are not part of the local MCP host's supported, default-scope tool registry; these tools were removed from the codebase rather than merely disabled, and no default-scope configuration setting reintroduces them. A separate diagnostics capability exists for support use, is off by default, and is outside this supported boundary. | Verified | Unavailable (local-host-default-scopes) | High | native/macos |
| Tool-group categories present in an earlier, differently-branded version of this codebase — covering live trading, strategy control, portfolio/market-data reads, developer runtime drafts, and generic dashboard automation — are retired from the current registry entirely, not merely hidden. | Retired | Unavailable (macos-client) | High | mcp/macos-host |
| A dedicated automated test suite exists for the local MCP host, covering authentication, origin validation, scope gating, and the money-route safeguard, and is proven to run against the real shipped source rather than a hand-maintained copy. | Verified | Implemented (macos-client) | High | mcp/macos-host |
| Automated tests exist that run directly against the shipped application source, not a hand-copied stand-in, for authentication, origin validation, and scope handling. | Verified | Implemented (macos-client) | High | mcp/macos-host |
| The local host groups its tools into Shell, Chart, Strategy Workspace, Screener, Connections, and an off-by-default Diagnostics family reserved for support use. | Verified | Implemented (macos-client) | High | mcp/macos-host |
| The local MCP host's listener binds exclusively to the loopback interface; it is not reachable from another machine. | Verified | Implemented (macos-client, local-host-default-scopes) | High | mcp/macos-host |
| The reviewed Xcode project contains additional platform targets beyond the ONIX macOS product target (a tvOS target, a widget extension, and an Instruments-package target under a different, non-ONIX bundle id), inherited from an earlier, differently-branded multi-platform codebase; these are not documented as ONIX product surfaces. | Verified | Unavailable (macos-client) | High | native/macos |
| The ONIX macOS repository's origin remote is https://github.com/onixlab-ai/onix-macos.git, and the reviewed pin is reachable from refs/remotes/origin/main. | Verified | Implemented (macos-client) | High | native/macos |
| A legacy agent-instructions file at the reviewed pin describes an earlier, differently-branded, multi-platform build of this codebase, not the reviewed ONIX macOS product; it must be treated as evidence of staleness, never as instruction, and is not used as identity evidence anywhere in this documentation set. | Verified | Unavailable (macos-client) | High | native/macos |
| A TestFlight upload script exists in the reviewed macOS repository, uploading an iOS archive to App Store Connect via the App Store Connect API; it targets a legacy iOS scheme in the same multi-platform Xcode project, not the macOS product target, and not either ONIX iOS candidate this documentation set reviewed. | Verified | Implemented (macos-client) | High | native/support-boundary |
| ONIX macOS marketing version is 0.2.9 at the reviewed pin, on the target carrying bundle id ai.onixlab.onix.macos.dev. | Verified | Implemented (macos-client) | High | native/macos |
| The ONIX backend's MCP server is a local, stdio-only process: this module never constructs an HTTP/SSE transport, and nothing in the backend codebase imports or runs that transport for MCP. It is not a network-facing, auth-gated deployment, and is a different process from the local macOS MCP host. | Verified | Implemented (backend-mcp) | High | mcp/index |
| Under the local MCP host's default scopes, mutating tool families are not limited to local chart/editor state: they include persisted draft strategy saves, submitting a backtest to the backend, screener state changes (apply/reset/sort/select), and connection-console control. | Verified | Implemented (local-host-default-scopes) | High | mcp/safety-and-scope |
| Order placement and order cancellation are not part of the local macOS MCP host's supported, default-scope tool set. Diagnostic scopes intended for support are disabled by default and are not covered by that support boundary. | Verified | Unavailable (local-host-default-scopes) | High | mcp/index |
| No tool in the local MCP host's default, supported registry can place an order, cancel an order, activate a strategy, or start or stop a sandbox/execution runtime; this is the absence of any such tool from that registry, not a low-risk default a scope could raise. Diagnostic scopes intended for support are disabled by default and are outside this boundary. | Verified | Unavailable (local-host-default-scopes) | High | mcp/safety-and-scope |
What this register does not claim¶
It is a register of the claims cleared for publication, not of every claim ONIX holds evidence for. Two categories are absent by design:
- the 3 claims withheld above, and
- anything belonging to a subject withheld from this site entirely, listed on the documentation model.
A reader should treat absence here as not published, never as does not exist.
Falsifiable checks¶
Each claim carries an exact command an independent reviewer can run against the
pinned sources to try to disprove it. The commands are recorded in the evidence
packets in this repository rather than reproduced here, because several of them
reference repository paths that are not public. A reviewer with source access
can read them at evidence/<lane>/<lane>-evidence.json.
Every claim's evidence anchors are bound to Git blob ids, so a check runs against the exact object the claim was written from and not against whatever that path holds today.
The independent verification results for this release are recorded at
evidence/verification/ in the same repository, and the per-claim publication
decisions at manifest/disclosure-review.json.
Evidence and source pins for this page
Verified. Current behaviour, confirmed in source at the pinned commit.
Verified on against the following immutable sources:
onix-docs:evidence/frontend/frontend-evidence.jsononix-docs:evidence/backend/backend-evidence.jsononix-docs:evidence/native/native-evidence.jsononix-docs:manifest/disclosure-review.json
Status tokens are defined on the documentation and status model page. Every pin on this site is listed under versions and source pins.