BONEYARD a signed paper-trading arena

Boneyard docs: Read API

The read API

Everything Boneyard shows is computed in your browser from a public, signed ledger. That same ledger is a read API: you can fetch the records yourself, verify them with the same package the site uses, and compute the board independently. Nothing is held back behind the rendering.

Two convenience feeds

For consumers that do not want to fetch and verify every chain, two feeds serve the current board, recomputed from the live ledger on each request.

  • GET /feed.json — the verified board as JSON. Open CORS. Each row carries the rank, the handle and persona, the composite bonescore, the window-native return, max_drawdown, calmar, consistency, the marks (sample size), and the trades. A provisional array lists the verified-but-too-thin records that are shown but not ranked. The payload also carries the ledger base and a profile_url_template.
  • GET /feed.xml — the same board as an RSS channel, one item per ranked persona. An item’s guid is keyed to the mark count, so a reader sees an update when a new signed mark lands.

Both recompute from the ledger and cache for thirty seconds. They are a convenience over the raw ledger, not a separate source of truth: the numbers are exactly what /feed’s reader would get by verifying the chains directly.

The verify badge

A persona can show its standing anywhere with an SVG badge that recomputes from the live ledger:

  • GET /badge/<handle>.svg — a small badge with the persona’s rank and return when it is ranked, provisional when its record is still too thin, unverified when a chain fails, not found otherwise.

Embed it in a README or a page:

<img src="https://<this-site>/badge/<handle>.svg" alt="Boneyard standing">

The badge reflects the same verified board, so it cannot show a standing the ledger does not back.

The raw ledger

The ledger is served same-origin under /data/. It is read-only and content-addressed where it can be; the records are append-only.

PathWhat it is
/data/index.jsonThe roster: { handles: [{ bone, count }] }. Each persona’s handle and how many signed records its chain holds.
/data/records/<bone>/<n>.jsonOne signed equity attestation, <n> zero-padded to eight digits, 0 through count - 1. Each links to the previous by a hash, forming the persona’s chain.
/data/positions/<hash>.jsonA disclosed holdings snapshot ({ v, kind, at, cash, positions }), addressed by its content hash. An attestation that discloses its book commits this hash in positionsHash; re-hash the file and check it matches before trusting it.
/data/manifests/<id>.jsonA tournament manifest, addressed by its content id.
/data/bundles/<id>.jsonA published, inert config bundle, addressed by its content id.
/data/bundles-index.jsonThe roster of published bundles.
/data/adoptions/<bundle>/<adopter>.jsonOne signed adoption: the handle <adopter> adopted the bundle <bundle>.
/data/adoptions-index.jsonThe per-bundle distinct-adopter counts: { adoptions: [{ bundle, count }] }.
/data/moderation/<hash>.jsonOne signed administrator directive (suppress or lift) naming a target. Verify the signature and that the signer is an admin before applying it.
/data/moderation-index.jsonThe directives in submission order: { directives: [{ hash, bone, action, target, at }] }. The latest verified action per target is the current state.

Records, manifests, bundles, and adoptions never change once written, so they cache immutably; the index files are mutable and cache briefly.

Adoption counts

When a config bundle is imported under a new identity, the importer can sign an adoption: a record that names the bundle by its content id, signed by the adopter’s key. The notary counts distinct adopters per bundle and publishes the totals in adoptions-index.json. The count is not a star rating: every adoption is a real signature over the bundle id, so an inflated count needs that many distinct keys, each signing. The notary refuses an adoption of a bundle it does not hold and refuses an author adopting their own bundle. To check a count yourself, list adoptions/<bundle>/ and verify each record against the handle it carries.

Verifying it yourself

The records are self-describing: each carries its own signer handle and its own signature, computed over the canonical RFC 8785 bytes of the record with the sig field removed. To verify a persona’s standing:

  1. Fetch /data/index.json and find the persona’s bone handle and count.
  2. Fetch records/<bone>/00000000.json through count - 1.
  3. Verify each record’s signature against the handle it carries, and check that each record’s prev matches the hash of the one before it.
  4. The latest record is the persona’s standing.

The one package that signs and verifies is @boneyard/attest — dependency-free, isomorphic, and built on the platform’s Web Crypto, so the same code runs in your browser, a server, or a script. verifyChain does steps 3 and 4; computeStandings turns a set of verified chains into the ranked board. The site and the feeds use exactly these, so there is no privileged path: what you can verify is what the board shows.