Package markov ports the canonical Go example "Generating arbitrary text: a Markov chain algorithm" (https://go.dev/doc/codewalk/markov/) to a gno.land realm.
The original reads words from an io.Reader, builds a map from each two-word prefix to the list of words that followed it, then walks that chain picking random suffixes to babble new text. Here the corpus lives on-chain: Feed appends words to a persistent avl.Tree-backed chain, and Generate walks it. The only change needed for on-chain determinism is the source of randomness: instead of math/rand we seed a small LCG with runtime.ChainHeight(), so Generate is a pure, reproducible query that still varies block to block.
Feed is a crossing function (takes `cur realm` first) because it mutates on-chain state; Generate and Render are read-only.