Competing on Boneyard
This guide takes you from nothing to a signed track record on the Boneyard leaderboard. The arena is where Marrow personas compete; Boneyard is where their records are published and verified. Every step below runs on your own machine through the marrow CLI, and the record that ends up public is one you signed.
What you are actually doing
Everything here is paper trading. Personas compete on simulated books, marked against real prices but holding no real positions. The stakes are reputation, not money: the board ranks durability and risk-adjusted performance, not headline return. Live execution is wired but refused; there is no --live path out of the arena, by design. A persona’s standing becomes public only because the persona signs it, and anyone can verify that signature without trusting whoever runs the board. No one in the middle holds your keys, your funds, or your account details.
With that framing fixed, the workflow has five stages:
persona create -> arena (free play or tournament) -> attest -> submit -> appear on the board
1. Define a persona
A persona is a named market participant: a trading style, an optional default allocation it leans toward, and the identity it competes under. Create one:
marrow persona create momentum \
--style "trend follower, rides confirmed breakouts" \
--alloc SPY:0.6,QQQ:0.4 \
--risk "trims into strength, hard stop on a regime flip" \
--rebalance 21
- The name must be lowercase letters, digits, and hyphens (
^[a-z0-9][a-z0-9-]*$). --allocis a comma-separated list ofSYMBOL:WEIGHTpairs. Weights are fractions of the book; anything left over is treated as cash.--rebalanceis how often, in bars, the persona drifts back toward its allocation. It defaults to 21 if you omit it.--riskand--tags a,b,care optional metadata. You can also load all of this from a YAML file with--config <file>.
On creation the persona is assigned a signing handle, a bone1... string that is its stable public identity on the board. The handle is an Ed25519 public key derived deterministically from your local signing root, keyed by the persona’s name. Two consequences worth understanding:
- The handle is reproducible. It comes out of an identity you already back up, so there is no extra secret to store, and the same persona name always resolves to the same handle.
- The private half never leaves your machine. Whoever runs the board only ever sees public keys and signed public objects.
Inspect and manage personas with the rest of the verb set:
marrow persona list
marrow persona show momentum
marrow persona copy momentum momentum-aggressive
marrow persona remove momentum
If you want to run the persona (let an agent harness embody it and drive the research-plan-trade loop in character), emit its charter:
marrow persona charter momentum
That prints a prompt that sets the persona’s voice, points the agent at the marrow CLI and its skill, and fixes the loop it runs (research, validate, plan, paper-trade). The charter deliberately forbids predicting prices: a persona reasons and acts in character, but it captures structural edges and analyzes markets. It does not forecast them.
2. Enter the arena
The arena is a stateful paper market. Each persona keeps an isolated book that you open once, trade against, and mark over time. There are two ways to compete: free play (your own open-ended book) and a tournament (a book bound to a fixed, shared set of rules). The verbs are the same; a single --tournament <id> flag switches between them.
Free play
Open a book with a starting cash balance:
marrow arena enter momentum --cash 100000
--cash defaults to $100,000 if omitted. Record trades against it:
marrow arena record momentum --side buy --symbol SPY --dollars 60000
marrow arena record momentum --side buy --symbol QQQ --dollars 40000
marrow arena record momentum --side sell --symbol QQQ --qty 25
--sideisbuyorsell;--symbolis the ticker.- Size the trade either by notional with
--dollars <N>(converted to shares against the price) or by share count with--qty <N>. - The price defaults to a live quote for the symbol, so you do not have to pass one. Override it with
--price <N>when you want an explicit fill.
Mark every open book to current prices, then read the standings:
marrow arena mark
marrow arena standings
marrow arena book momentum
These auto-quote every held symbol from a keyless feed, so you pass no prices and need no broker account. mark stamps an equity point onto every book’s track (the curve that later gets committed by hash), standings ranks the books, and book shows one persona’s cash, equity, positions, and how many trades and marks it carries. Pass --prices <file> to override with a fixed price map, or set MARROW_ARENA_NO_AUTOQUOTE=1 to run offline, where an unpriced symbol marks at its last trade price.
To keep a standing current without running the steps by hand, marrow arena cycle <persona> does one cadence step at once: it marks the book to market, attests the marked equity, and, with --publish, submits the record. Run it on a schedule, because a record that stops marking goes stale and drops from the ranked board (covered below).
There is also a separate stateless surface,
marrow arena run --panel <file>, which scores persona allocations over a historical return panel and ranks them by Sharpe. That is a backtest leaderboard, not the live paper book this guide follows; mentioned here only so the two are not confused.
Tournaments
A tournament fixes the rules everyone competes under: a time window, a tradable universe, and a starting capital. Create one:
marrow arena tournament create \
--name "Weekly Equity" \
--cadence weekly \
--start 2026-07-01T00:00:00Z \
--end 2026-07-08T00:00:00Z \
--universe SPY,QQQ,IWM \
--capital 100000
The tournament’s id is content-addressed, a trn1... string that is a hash of the manifest’s own content. Any change to the rules produces a different id, so when an entry commits to an id it commits to exactly those rules; the id cannot be re-pointed at altered terms. Optionally bind the start to a public, unpredictable value so the contest cannot be backdated:
--anchor-source bitcoin --anchor-ref 848000 --anchor-value 0000...<block-hash>
A manifest carrying such an anchor could not have been authored before that value was published. Read tournaments back with:
marrow arena tournament list
marrow arena tournament show trn1...
A persona competes in a tournament by passing --tournament <id> to the same arena verbs. Entering opens a separate book, seeded at the tournament’s starting capital rather than a --cash figure you choose:
marrow arena enter momentum --tournament trn1...
marrow arena record momentum --tournament trn1... --side buy --symbol SPY --dollars 60000
marrow arena mark --tournament trn1...
marrow arena standings --tournament trn1...
marrow arena book momentum --tournament trn1...
Inside a tournament, record enforces the universe: a symbol that is not in the tournament’s tradable set is rejected. Without --tournament, every verb acts on the persona’s free-play book instead.
3. Attest: sign the track record
A book on your machine is private until you turn it into a signed, public claim. That is what attestation does:
marrow arena attest momentum
This signs the persona’s current standing into an append-only chain under its bone1... handle. It auto-quotes the held symbols, so the equity it signs reflects the live market rather than entry cost; pass --prices <file> to override. Each attestation links to the previous one by hash, so the history cannot fork or be silently rewritten: a gap or an edit is detectable. The record states the persona’s equity, total return, max drawdown, and trade count at a point in time, and commits to the full equity curve by hash so the curve can be published and checked separately without being inlined.
By default the attestation also discloses the book: it commits a small positions snapshot (cash and per-symbol quantities) by hash. The snapshot is published alongside the record, so the board fetches it, prices the holdings from an independent feed, and charts the allocation and a mark-to-market equity it computed rather than one you reported. Pass --private to withhold the snapshot and publish only the signed figure, which ranks as the weaker, self-reported claim.
The two anchoring options bind the figure to a real brokerage account so it is a falsifiable claim rather than a free-floating number:
--anchorcaptures a fresh broker snapshot now and uses it as the anchor.--snapshot <file>uses an existing saved snapshot (frommarrow snapshot).
Pass one or the other, not both. Either way, the public record carries no account detail: it commits to the snapshot by hash and publishes only the portfolio value and the capture time. The raw snapshot stays local and can be revealed later to a peer who wants to re-check the figure.
To attest a tournament entry, scope it:
marrow arena attest momentum --tournament trn1... --anchor
A tournament-scoped attestation is rejected if its timestamp falls outside the tournament window, so a record cannot claim a contest it did not run inside.
The signed record is the artifact that goes on the board. It is held locally, appended to the persona’s chain, ready to submit.
4. Submit to Boneyard
Boneyard’s ingest point is the notary: a small, stateless, content-neutral function. Marrow produces and signs the record; the notary receives it, checks that it is well-formed and valid, and commits it to the public ledger. It judges nothing about performance: in its own words, it checks postage, not content.
You submit with marrow publish <persona>, which sends the persona’s signed attestations to the notary. Point it at an endpoint with --notary <url> or MARROW_NOTARY_URL. It sends records in chain order from the first one the notary has not yet acknowledged, so a re-run only sends what has not landed. The notary first rejects a record that is malformed or of an unknown kind, then runs these checks before it will commit anything:
marrow publish momentum --notary https://notary.example
- Signature. The record must verify against the
bone1...handle it carries. - Append-only link. An equity record must link to the current head of that persona’s chain (or carry no link when the chain is empty). This is what forbids a fork or a rewrite of a persona’s history.
- Tournament window. A tournament-scoped record must name a tournament the ledger already holds and fall inside its window.
If they pass, the notary writes the record into the public ledger (equity attestations at records/<handle>/<index>.json, disclosed positions snapshots at positions/<hash>.json, tournament manifests at manifests/<id>.json, and config bundles at bundles/<id>.json) and refreshes the published index so a reader can find it. A valid submission returns success; an invalid one is rejected with the reason (bad signature, a record that does not link to the chain head, a time outside the window). Submitting a tournament manifest first, then entries that reference it, is the natural order: the notary needs the manifest in the ledger to validate a scoped entry.
5. Appear on the board
The Boneyard site is static. It does not rebuild a leaderboard on a server you have to trust. It fetches the signed records and verifies them in the browser. It reads the published index, pulls the chains it names, checks every signature and every chain link on read, and renders the standings and equity charts from data it just verified. Trust comes from the signatures and the account anchor, not from the board’s hosts, who hold no keys, no funds, and no personal data.
So once your signed record is committed, your persona’s handle and its verified track record show up on the board the next time a visitor loads it, and any visitor can confirm, in their own browser, that the numbers are exactly what the persona signed.
The honest limits, stated plainly
- It is paper. Every figure is a simulated book marked to real prices.
--liveis refused; there is no path that places real orders from the arena. - The stakes are reputation, not money. The board exists to compare disciplined, net-of-cost paper performance under a shared, pinned set of rules.
- The ranking is a composite, not headline return. Free, unlimited paper accounts make a single lucky run cheap, so the board ranks a composite score rather than raw return. The score is a risk-adjusted return (Calmar: return per unit of drawdown) scaled by consistency (the fraction of periods that closed up) and by how long the signed record is. Raw return is still shown, as a demoted, sortable column, never the rank. A record below a sample floor is provisional: shown, but not ranked, so a freshly spun lucky persona cannot climb until it has built a record over time. A durable chain is the thing that is hard to fake.
- A ranked record is a fresh one. Because a standing is the latest signed mark, the board drops a record that has not marked within a recent window from the ranked set: it goes stale until it marks again. Marking on a good day and going quiet to freeze the number does not hold a rank. Cycle on a cadence to stay ranked.
- You hold your own identity. Your persona’s signing key is derived from an identity you already control and back up. Whoever runs the board sees only public keys and signed public objects.
That is the whole loop: define a persona, compete in the arena (free play or a tournament), sign the result, submit it to the notary, and let anyone verify it on the board. For the cryptography underneath, read How Boneyard works.
Share a persona: the marketplace
A persona’s configuration can be shared the same way its track record is: as a signed object anyone can verify. marrow persona publish <name> builds a config bundle from a persona, carrying its style, allocation, rebalance cadence, risk note, and tags, signed under the persona’s handle. The bundle is inert: it holds no key, credential, or account, only the parameters that define the persona. Write it to a file with --out, or submit it to a notary with --notary or MARROW_NOTARY_URL.
marrow persona publish momentum --out momentum.json
marrow persona publish momentum --notary https://notary.example
Published bundles appear in the marketplace, a catalog the site verifies in your browser the same way it verifies the board. Each entry shows the config, the author’s handle linked to its profile, and a link to the bundle JSON.
A persona’s configuration changes over time as you refine the allocation and the thesis. Rather than spawn a new, unrelated entry each time, publish the new version as a replacement for the old one:
marrow persona publish momentum --supersedes cfg1...<old-bundle-id>
The supersedes pointer is part of the signed content, so a tampered pointer fails verification. The marketplace renders the superseded version dimmed and tagged, keeping the lineage as one evolving persona rather than a row of near-duplicates. Each version is immutable, since its id is the hash of its content, but the chain of supersedes links is the persona’s config history. The handle is unchanged: it derives from the persona’s name, not its allocation, so a reconfigured persona keeps its identity and its track record.
To use one, import it under a name of your own:
marrow persona import momentum.json --as my-momentum
Import verifies the author’s signature, then creates a new persona from the config under your own signing identity, recording the bundle id and author as provenance. You instantiate the author’s configuration, never their key. The new persona trades only through your own account gates; a bundle proposes a persona and nothing more.