Telemetry off
Documentation

Documentation

38. v0.18.0 — Coordinated paper trading

Created
Oct 4, 2026
Updated
Oct 4, 2026

Release candidate prepared 2026-10-04. This release adds coordinated paper trading as a default-off capability: where a deployment enables it, one open tab executes the live paper account and every other tab follows it, so an action taken in any tab is applied exactly once and its result appears everywhere. Nothing about paper trading changes until a deployment turns the controls on. The release also carries the cross-tab alert and coordination fixes from the Phase 0–5 audit and two dependency upgrades that reached main after v0.17.0. Follows v0.17.0.

Added

  • One tab executes the live paper account; the others follow it. Today every tab runs its own paper engine against its own chart feed, and the documentation asks you to keep active trading in one tab at a time. With coordinated paper trading enabled, every action on the live account — placing, modifying or canceling an order, closing or reversing a position, changing settings, resetting or importing — is recorded as a request that only the executing tab applies, exactly once. Fills, positions, orders and settings then appear in every tab. Closing the executing tab hands the job to another open tab, which resumes from the last bar the account was evaluated against instead of re-walking it, so a fill that already happened is never repeated and an order that was waiting is not skipped.

  • Queued is not applied. Until the executing tab applies a request, the order ticket stays open and says the action was accepted but not applied yet, the settings dialog keeps your draft behind a Recorded, not yet applied notice, an import is reported as recorded rather than imported, and the assistant's trading tools answer "Not yet applied" rather than done. A request your tab could not record — storage unavailable or full, or too many requests still waiting — is reported as Paper trading action not confirmed with the reason, and nothing was applied. Actions that need exact state (placing or modifying an order, editing brackets, partially closing a position, resetting or importing) are refused when another tab changed the account first, so you re-issue them from the current state; settings changes, cancels, reversals and full closes apply onto the current state.

  • The account keeps being evaluated for symbols no chart is showing. The executing tab opens its own one-minute execution feed for every symbol with a position or a working order, whether or not any pane shows it, and walks the closed bars the app was shut for before live prices take over, the way v0.17.0's offline catch-up does. A gap it cannot reconstruct still fills nothing and says so.

  • Loading and unavailable are stated, not guessed. Right after a page loads, paper actions are refused with a short "still loading" message until the tab has read the account state; no provisional account is shown. A tab that cannot read its paper state after several attempts — about 23 seconds of consecutive failures — reports paper trading unavailable and asks you to reload the page. Other tabs are unaffected.

  • Bar replay stays in the tab that started it. A replay account is owned by its tab under a lease, the other tabs keep trading the live account, and ending the replay archives its account for every tab. A replay whose tab vanished is archived once its lease lapses, with its trades preserved read-only.

  • Shadow mode comes first. A separate control elects a shadow host that evaluates the same price samples as the per-tab engines and records only decision digests for comparison; it cannot fill, persist, notify or emit telemetry. Authority mode requires shadow mode, and both require the browser-concurrency protocol control. The paper trading overview and Settings, Reset & Export now describe the per-tab and coordinated modes side by side.

Fixed

These fixes apply where the coordinated alert controls are enabled. They reached main after v0.17.0 as the remediation of an independent audit of the Phase 0–5 browser concurrency work.

  • An older tab saving alerts the old way could be overwritten. A tab opened after a pre-coordination tab had written alerts did not notice, elected a second evaluator, and mirrored over the other tab's edits. Startup now compares what the older tab wrote with the coordinated copy; a difference pauses coordinated alerts for this page load, keeps the older tab's changes in a small local quarantine rather than merging or discarding them, and asks you to close the other tab and reload. See Notifications, Triggered Log & Managing Alerts.
  • A paused alert authority gave up its lease. Pausing released the lease, so another tab could take over in the middle of a pause the documentation said would hold. It now holds.
  • Switching windows during an alert could lose the notification. A focus or visibility change while a tab was claiming a notification abandoned the claim after the record was already marked presented, so the toast appeared nowhere. A claim is now abandoned only when the tab closes or the runtime restarts; a hidden tab queues the toast until it is visible again.
  • A hidden tab lost its authority every minute. Under the browser's background timer throttling a hidden tab's lease could lapse before it renewed, and no other tab could take the lock it still held. A holder whose lease lapsed now reclaims it in place, and a visible tab can take over a lapsed lease.
  • A permanent storage failure on one alert was retried forever. Corrupt, invalid, newer-schema and closed-store failures now drop that alert's commit lane, are counted, and surface in diagnostics instead of blocking every flush.
  • A different app version in another tab is a visible stop, not a silent one. A protocol mismatch, or an older tab writing the old way, now stops the coordination layer for the page's life and shows a Cross-tab safety notice asking you to close or reload the other tab, then reload this one.

Changed

  • Settings, import, reset and account deletion in paper trading share one action path. In the default per-tab mode they apply immediately, as before. Where coordinated paper trading is enabled they are requests like any other and are announced as applied only once the executing tab has applied them.
  • Paper trading documentation separates per-tab from coordinated mode in Where it is stored and Storage and limits: what is saved where, what "queued" means, and what the loading and unavailable states look like.

Under the hood

  • Two new exact-value rollout controls, NEXT_PUBLIC_BROWSER_CONCURRENCY_PAPER_SHADOW and NEXT_PUBLIC_BROWSER_CONCURRENCY_PAPER_AUTHORITY, both default off and fail closed; the README documents all fourteen. A production build with every domain control off bundles none of the paper coordination code, and the release checks prove it by scanning the retained chunks.
  • When coordinated paper trading is enabled, the live account moves from a local-storage key to the browser's IndexedDB database fractal-paper-broker; the local-storage key then holds only a marked rollback mirror written by the executing tab, and the recovery backup written before a reset or import carries the same markers. Nothing is touched while the controls are off, and the legacy format is unchanged.
  • The browser evidence toolchain for the cross-tab gates now runs on exactly one Playwright release, records the toolchain it ran on, and binds every artifact to one evidence run, so an interrupted rerun can never leave a readable "passed" claim behind.
  • With the protocol control on, a legacy Massive connection now waits at most 30 seconds for coordinated leases to drain and then fails closed with a diagnostic, instead of waiting indefinitely.
  • Dependencies: Vitest 5.0.1 (the test runner) and google-auth-library 11.0.2 (server-side Vertex AI credentials), both merged after v0.17.0. No other direct dependency changes.

Verification

  • The complete automated suite (403 files / 3,542 tests, 4 of them opt-in CSV reference-data cases that stay skipped), TypeScript, the zero-warning ESLint baseline, and the optimized production build (132/132 static pages) passed on the release-preparation tree. A second production build with every browser-concurrency control enabled also passed; the retained chunks of each build were scanned for the coordination code, absent from the first and present in the second.
  • 141 tests are new since main: the coordinated paper trading suites — a shared repository contract run against both the in-memory and IndexedDB implementations, including property tests for command idempotency, revision accounting and monotonic cursors; the authority host; the follower; the legacy bridge and migration; identity and ledger; instrument metadata; the disabled facade; and the action outcomes — plus the workspace composition and the structural assertions that pin the release-gate toolchain.
  • The pull request went through four independent review passes with 26 findings in all (P6-IA-01 to P6-IA-17 and P6-RR-01 to P6-RR-09), each closed with a fix and a committed regression. The final pass returned approve with comments and no open product finding.
  • Not run: the enabled and disabled browser matrices on Chromium, WebKit and the pinned Linux Firefox container. They need the exact Node v24.15.0 host with Docker, which the preparation environment does not have. Both paper controls stay off until that evidence run passes.

Next steps

Read how the two modes differ before enabling anything.

Next: Paper Trading Overview