everything on this page is the actual shape of the engine, restated in source. it is short on purpose. the fewer moving parts a system has, the fewer places a discretionary hand can rest, and clesis is an argument that zero such places is achievable.
clesis is four small functions run in a fixed order, forever. the screen decides what exists. the thesis turns a name into sentences and a number. the stake turns the number into a fraction of the book. the seal writes first and signs second. beneath them a fifth process, the grader, wakes when a horizon lapses and appends the verdict. none of the five accepts instructions from outside, and none can amend what an earlier one wrote.
a hard filter. a name that fails any test here is never shown to the model at all.
// the screen. what the model is allowed to see. // failing any line makes a name invisible to the whole loop. type Name = { mint: string capUsd: number pooledUsd: number ageDays: number } const CAP_FLOOR = 2_500_000 // small enough to move, large enough to exist const POOL_FLOOR = 150_000 // an exit has to be possible at size const AGE_FLOOR_DAYS = 10 // ten days alive is the price of admission const BOOK_LIMIT = 5 // a sixth position is refused unconditionally const visible = (n: Name, openPositions: number): boolean => n.capUsd >= CAP_FLOOR && n.pooledUsd >= POOL_FLOOR && n.ageDays >= AGE_FLOOR_DAYS && openPositions < BOOK_LIMIT
the model is asked for a reason it is willing to be graded on, not a signal.
// the thesis. the model answers with the sentences that will // sit above this trade for as long as the record exists. type Thesis = { act: "enter" | "pass" confidence: number // 0 to 1. the grade lands on this number. horizonHours: number invalidation: string // the condition that proves this wrong body: string // the reason, first person, plain } async function writeThesis(name: Name, tape: Tape): Promise<Thesis> { const reply = await anthropic.messages.create({ model: "claude-fable-5", max_tokens: 500, system: "you run a small solana book under your own name and you are " + "graded on every confidence you state. answer as json with keys " + "act, confidence, horizonHours, invalidation, body. body is two " + "to six sentences, first person, no hedging language. when the " + "honest confidence is low, pass. a pass is recorded like a trade.", messages: [{ role: "user", content: JSON.stringify({ name, tape }) }], }) return JSON.parse(reply.content[0].text) }
confidence becomes size through a fixed curve. no judgment happens in this step because it already happened in the last one.
// the stake. a stated number in, a share of the book out. const FLOOR = 0.6 // below this the correct size is zero const CEILING = 0.12 // no name exceeds this share, whatever the words say const stake = (confidence: number): number => confidence < FLOOR ? 0 : Math.min(((confidence - FLOOR) / (1 - FLOOR)) * 0.3, CEILING)
the store accepts the entry before the chain sees the swap. if the write fails, the trade does not happen. the order of those two lines is the entire point of clesis.
// the seal. written first, signed second, never the reverse. async function seal(name: Name, t: Thesis): Promise<void> { const row = await store.append("theses", { mint: name.mint, opened_at: clock.now(), side: t.act, confidence: t.confidence, horizon_hours: t.horizonHours, size_fraction: stake(t.confidence), invalidation: t.invalidation, body: t.body, closed_at: null, // the grader appends. nothing replaces. result: null, score: null, }) if (t.act === "pass" || stake(t.confidence) === 0) return const sig = await swap(wallet, name.mint, stake(t.confidence)) await store.append("fills", { thesis_id: row.id, sig, filled_at: clock.now() }) }
the grader is the fifth process and the only one that touches an old row, and even it may only fill the three fields that were born null. it wakes when a horizon lapses, reads what the market did, computes the score, and appends the verdict. it has no opinion, no model call, and no way to soften a number. the loop then continues, one second at a time, with the record one row longer.
what is absent from this page matters as much as what is on it. there is no function that edits a row, no function that pauses the loop, no parameter that a person adjusts when the record looks bad. those absences are not oversights. they are the product.
clesis