AI odds on every mint, sealed on-chain first.

sybiliCC / model card / commit log
Test the OpenAPITen endpoints on the stream and the proofs. Open one, press Execute.
Docs

How it works

Re
A probability for every new Solana mint, sealed on-chain before the outcome.
Model
Sequence + graph, trained on the first slots of every launch.
Record
Commit first, reveal after. Every mint, every window.
State
Closed. First reveal soon.

§00 Abstract

sybiliCC is a forecaster for every new Solana mint. It reads the first slots of each launch: the order flow, the holder graph, the funding chains behind every early wallet. For each mint it outputs one number, the probability that the coin runs inside a fixed horizon. Before any outcome exists, that number is hashed with a secret salt, folded into a Merkle tree with every other mint from the same window, and the root is written on-chain. When the horizon closes, the salts open. Anyone can rebuild every leaf, check it against a root that landed earlier, and score the model on all of its calls. Nothing can be edited, dropped or picked after the fact.

stage     in                          out
ingest    shreds + geyser             slot log
window    slot log, first k slots     frozen events
encode    events + wallet graph       z(mint)
score     z(mint)                     p(run | W)
seal      p, salt                     leaf
commit    leaves of window w          root  ->  chain @ s_c
reveal    epoch seed                  every salt, every leaf
record    reveals + chain             public score

§01 Universe

The universe is every mint that opens a market on Solana: bonding-curve launchpads, curve migrations and fresh AMM pools across the major programs. A mint enters at its first trade, whether or not it ever trends. There is no filter for interesting. The rule that defines the universe is public and versioned, so anyone can rebuild the full list of mints for any window from chain data alone and compare it, leaf by leaf, with what was committed.

universe.v1 {
  programs   [ bonding curves, migrations, cpmm, clmm, dlmm, whirlpools ]
  enter_on   first_trade(mint)        // first swap that moves reserves
  key        (slot, tx_idx, ix_idx)
  exclude    none
  root       merkle(sort(mints in window))
}

§02 The first slots

The model sees a launch only through a window W: the first k slots after its first trade. Every event inside W is frozen when the window closes. Everything after W is out of sight. The cutoff is enforced by slot number inside the log, never by a wall clock, so no feature can peek past it, offline or live. k is fixed per horizon and published with each model version.

W(m)    = [ s0, s0 + k )          // s0 = slot of the first trade
events  = log.where(m in accounts, slot in W)
freeze  at s0 + k                 // features are a pure function of events
assert  max(slot(e)) < s0 + k  for every input e

§03 Sequence model

The tokens of W go through a causal transformer that cross-attends to the mint's graph context. The head outputs a hazard instead of a yes or no: the chance of a run in each future time bin, given no run before it. The probability of a run within the horizon is one minus the product of not running in every bin. Every launch the chain has ever seen is a training example, rebuilt from the archive with the live decoder.

z        = Transformer(e_1 .. e_n ; cross = ctx(m))
lambda_t = sigmoid(w_t . z + b_t)          // t = 1 .. T bins over h
p        = 1 - prod_t (1 - lambda_t)       // P(run within h | W)
loss     = discrete-time survival NLL
           + log loss on p                 // a proper scoring rule

§04 Seal

Each scored mint becomes a leaf: a hash of the model version, the mint, the window, the horizon, the quantized probability and a salt. Salts come from an epoch seed whose own hash is published when the epoch opens, so the model cannot choose salts later. Leaves are sorted by mint and folded into a Merkle tree with domain-separated hashing. Every mint in the universe gets a leaf, the ones that will run and the ones that will die, so a missing call shows up as a missing leaf.

salt(m)  = HMAC-SHA256(seed_e, mint || s0)      // seed_e hidden until the epoch ends
leaf(m)  = SHA256(0x00 || ver || mint || s0 || h || q(p) || salt(m))
node     = SHA256(0x01 || left || right)
q(p)     = round(p * 10^4) as u16
opened   = SHA256(seed_e)                         // committed when the epoch opens

§05 Commit

Window roots go on-chain through a small Anchor program. Each commit writes the root, the leaf count and the universe root into an account derived from the model and the window, signed by the model key. The slot the transaction lands in is the timestamp, so nobody has to trust a clock. Commits carry a priority fee and a bundle tip to land fast; one that lands on a dead fork is sent again, and the clock starts wherever it finally lands.

#[account]
pub struct WindowCommit {
    model:          Pubkey,     // model authority, ed25519
    version:        u16,
    window:         u64,        // first slot of the window
    root:           [u8; 32],   // merkle root of leaves
    universe_root:  [u8; 32],   // merkle root of mints in window
    n_leaves:       u32,
    landed:         u64,        // Clock::get()?.slot
    epoch:          u64,
}
seeds = [b"commit", model, version, window]
ix    commit_root(window, root, universe_root, n_leaves)

§06 Reveal

When the longest horizon of an epoch has closed, one transaction opens the seed. Every salt follows from the seed, and every leaf follows from the salts and the published probability file. The file's hash is part of the reveal, so the file cannot change later. The program checks the seed against the hash posted when the epoch opened. A leaf that fails to rebuild scores as the worst possible call.

ix reveal_epoch(epoch, seed, file_hash)
   require!(sha256(seed) == epoch.opened)
   emit!(EpochRevealed { epoch, seed, file_hash })

verify(w):
   file   = fetch(file_hash)            // p per mint, content-addressed
   leaves = [ leaf(m, file[m], salt(m)) for m in universe(w) ]
   assert merkle(leaves) == commit(w).root
   assert commit(w).landed <= first_label_slot(w)

§07 Public record

Scores are computed from reveals and chain data alone: Brier, log loss and calibration curves, per horizon and per launch family, over every mint in every window. Because the denominator is the committed universe, there is no way to show only the hits. Every model that scores in production commits its own stream, challengers in shadow included, and retired versions stay on the record.

record(version) = {
  windows   every window since genesis(version)
  mints     sum n_leaves                 // == universe, recountable
  scores    brier, log loss, reliability bins, resolution
  split     horizon x launch family
  shadow    challengers commit too
  retired   kept, never deleted
}

§08 Non-goals

No buy button, no auto-trading, no signal group, no promise. A probability is a probability: a high call can still miss, and the record keeps every miss.

buy button     no
auto-trade     no
signal group   no
cherry-pick    detectable   // a missing leaf
promise        none

§09 Access

Closed for now. Every wallet that connects is sealed into the draw for the first seats on the private stream. First reveal soon.

status    closed
seats     draw, per connected wallet
stream    private, per seat
record    public, after each reveal
release   soon

— sealed —

Docs seat guest · s+0000

Every new mint

Read, scored and sealed before anything happens. Tap a row to open the call.

SYBILI

    
                

    Seal your own call

    Your calls

    Each one is hashed with a salt only you hold. It opens after the horizon, next to the model.

    The record

    Every leaf, every window. A miss stays on the board.

    Leaves

    hollow sealed · solid ran · hatched missed · ringed yours

    Calls against outcomes

    Windows

    windowleavesrootlanded