the fly experiment

the fly experiment, in full

the companion to the article. everything the article summarizes, stated exactly.

reading this page

this page is written for someone who intends to rerun the experiment rather than believe it. it states every constant of the contract, every parameter of the model, every rule of the rig, and the byte layout of every file the rig publishes, with the exactness needed to reproduce a receipt from its frames. where a number appears it is a compiled constant, a published count with its source, a value derived by arithmetic anyone can repeat, or a live read in a slot that is blank until the read succeeds. nothing on this page is illustrative.

three things to hold in mind. the contract counts blocks and only blocks; seconds appear only where the site measured them. the model is deterministic: the same frames over the same circuit with the same parameters produce the same spikes, to the last spike, on any machine, because there is no random number anywhere in it. and the fly key is the only private thing in the experiment, and the contract limits what it can do to one function under a cap.

the experiment in one paragraph

a token on pons pays creator fees to a contract called the arena. collect splits every fee in half between a fly arm and a metronome arm. every 128 blocks the rig samples the token's price at sixteen blocks, renders sixteen frames of a drifting grating onto the 892 columns of the fly's right eye, runs a leaky integrate and fire model over the fly's real motion vision circuit for 800 ms of model time, counts the spikes of the left and right horizontal system cells, and derives a turn. if the price fell and the fly turned left to follow the drift, the rig calls flyAct with kind bite and a size from one to eight; otherwise with kind rest and size one. the arena spends size eighths of a sixteenth of the fly budget buying the token and sends it to the dead address, and writes a receipt carrying the keccak256 of the frames and the keccak256 of every neuron's spike count. anyone may call controlAct every 128 blocks, which spends a sixteenth of the metronome budget the same way with zero hashes. if the fly key is silent for 256 epochs anyone may sweep its budget to the metronome. the site reads the arena and the published frame files and reports tokens burned per coin for each arm.

the fly and the release

the connectome is the male central nervous system release of janelia flyem, produced with google research and published in 2026 on neuprint as male-cns:v1.0, under a cc by 4.0 license. the whole release contains 164,838 neurons, 11,751 cell types and 171,901,440 synapses, and the visual system counts used on this site come from the reiser lab's cell type explorer for the same release: 892 L1 cells in the right optic lobe and 884 in the left. the experiment uses the right eye only, because a grating drifting horizontally across one eye is enough to drive the horizontal system of both lobula plates through the pathways the release contains, and because one eye keeps the frame format fixed at 892 bytes. every other count on the site, for L2, Mi1, Tm3, Tm1, Tm2, Tm4, Tm9, the eight T4 and T5 subtypes, HSN, HSE, HSS and the descending set, is read from neuprint by the rig at import and stored with the circuit; the site renders those counts from the circuit_types table and leaves them blank until the import has run.

the circuit file

the rig imports the circuit once and writes it to circuit.json in the frame store. the file has four arrays. types lists every cell type included, in the order given in the article's table, followed by the descending types found. neurons lists every body id included, ascending, each with its type index, side (L or R), and for L1 cells of the right eye its lattice index from 0 to 891. edges lists every synapse group between two included neurons as a triple of presynaptic index, postsynaptic index and count, followed by a sign of plus one or minus one from the presynaptic neuron's predicted transmitter (acetylcholine plus, gaba and glutamate minus, anything else zero and excluded). params repeats the model parameters. the descending set is chosen by one rule: the thirty two neurons outside the listed types that receive the most synapses in total from HSN, HSE and HSS cells, on both sides. the keccak256 of the file's bytes is printed on the state block after the site fetches and hashes it, and a reader who hashes the same url gets the same value or the file has changed.

the lattice assignment

the 892 L1 cells of the right eye are assigned to lattice indices as follows. where the release publishes hexagonal column coordinates for a cell, the cell's row is its second coordinate offset so that the smallest is row zero, and its position within the row is its first coordinate offset likewise; rows are then packed into the 28 row layout of fig. 1 in order, with any row longer than the layout allows spilling its extra cells into the nearest shorter row. where a cell has no published coordinate it is placed last, ordered by the position of its cell body along the eye's longest principal axis, into whatever lattice positions remain. the assignment is computed once, written into circuit.json, and never recomputed, so index c means the same cell in every frame of the experiment. the layout is not a claim about the geometry of the eye; it is a stable addressing scheme so that frames are comparable and hashable.

the grating rule

sixteen sample blocks: the epoch's first block plus multiples of eight, so blocks b, b plus 8, up to b plus 120. at each the rig reads the market's reserves by an archive call at that block and computes the price as coin reserve over token reserve, both in their smallest units. the phase of frame k is the phase of frame k minus one plus 128π times the natural log of price k over price k minus one; the phase of frame zero is zero, and the phase does not carry across epochs. luminance of column c in frame k is one half plus one half times the cosine of 2π times x_c over 8 plus φ_k, where x_c is the column's position within its row minus half the row width, so the grating is centered. luminance is quantized to a byte by rounding 255 times the value. a fall in price makes φ decrease, which drifts the pattern toward decreasing x, the fly's left. the constant 128π means a move of one part in 128 advances the phase by one full cycle of eight columns per frame step, which at a 50 ms hold is a drift of 160 columns per second; a move of one part in 1,280 is 16 columns per second. both are within the range of speeds over which T4 and T5 respond.

the model

every included neuron is a leaky integrate and fire unit with the parameters of shiu, xie, shiu and colleagues (2024): membrane time constant τ of 20 ms, resting potential −52 mV, spike threshold −45 mV, reset potential −52 mV, absolute refractory period 2.2 ms, synaptic jump 0.275 mV per synapse count with sign from the transmitter, time step 0.1 ms. there is no synaptic delay beyond one step, no synaptic time constant, no noise, no adaptation, and no learning. the state of a neuron is its membrane potential and the time of its last spike. at every step, for every neuron, the potential decays toward rest by a factor of e to the minus dt over τ, then receives the sum of the jumps from every presynaptic neuron that spiked in the previous step, then, if it is past its refractory period and at or above threshold, it spikes, is reset, and its spike is delivered on the next step.

the stimulus enters at the lamina. for each column c, let ΔI be the change in the column's luminance between the current frame and the previous one, expressed on the zero to one scale, and let g be 8 mV. at every step during the 50 ms hold of a frame, the L1 cell of column c receives an input of g times ΔI times e to the minus t over 10 ms if ΔI is positive, and the L2 cell receives g times minus ΔI times the same decay if ΔI is negative, where t is time since the frame began. this is a brightening current into the on cell and a darkening current into the off cell, decaying over 10 ms, which is the crudest honest description of what photoreceptors and lamina do to a luminance step. no other neuron receives external input.

τ (membrane)          20        ms
V_rest                −52       mV
V_thr                 −45       mV
V_reset               −52       mV
refractory            2.2       ms
w per synapse         0.275     mV
dt                    0.1       ms
frame hold            50        ms
frames per epoch      16
steps per epoch       8000
input gain g          8         mV
input decay           10        ms
Λ (grating period)    8         columns
κ (phase gain)        128π      rad per unit log return

the step procedure

for step s from 0 to 7999: let k be floor of s over 500, the current frame. for each of the 892 right L1 cells and their paired L2 cells, add the lamina input for frame k at time (s mod 500) times 0.1 ms. for every neuron, V equals V_rest plus (V minus V_rest) times 0.995012 (which is e to the minus 0.1 over 20), plus the summed jumps from spikes delivered this step. for every neuron whose last spike was more than 2.2 ms ago and whose V is at least −45 mV: record a spike at s, set V to −52 mV, and add its outgoing jumps to the delivery buffer for step s plus 1. after the loop, the spike count of every neuron is the number of spikes recorded for it. the horizontal system totals are the sums of the counts of HSN, HSE and HSS cells on each side. the whole procedure is integer indexed and floating point in double precision; the reference implementation in the rig sums jumps in a fixed order (ascending presynaptic index) so that the result is bit identical across runs.

the turn rule

t equals the right horizontal system total minus the left. the epoch's drift is left if the price at sample sixteen is below the price at sample zero, right if above, and none if equal. kind is bite if and only if drift is left and t is negative. size is one when kind is rest; when kind is bite, size is the ceiling of eight times the absolute value of t over the sum of both totals, clamped to one through eight. if both totals are zero, kind is rest. the rule reads only the horizontal system; the descending neurons in the circuit are simulated so that their spike counts are in the digest and available to anyone who wants to read them differently, but the experiment commits to this reading before any receipt exists.

the frame file

for fly act n the rig writes frames/n.json with these fields, in this order: index (n), block (the block of the act), samples (seventeen strings, the sixteen sample block numbers and the epoch's first block, followed by the sixteen prices as decimal strings of the raw ratio), phases (sixteen numbers), frames (sixteen arrays of 892 integers from 0 to 255, in lattice order), hs (an object with left and right integer totals), turn (t), kind (0 or 1), size (1 to 8), spikes (an array of one unsigned integer per neuron in circuit.json order). the frame hash is the keccak256 of the 14,272 bytes formed by concatenating the sixteen frames in order, each column's luminance as one byte. the spike digest is the keccak256 of the spike array encoded as two bytes per neuron, big endian, in file order, with any count above 65,535 clamped to 65,535 (which cannot occur in 8,000 steps with a 2.2 ms refractory period, whose ceiling is 364). the file is written before the act is signed, and it is never modified afterward.

verification

the site verifies every fly receipt as follows. it fetches frames/n.json. it rebuilds the 14,272 byte frame buffer from the frames field and computes keccak256 with viem in the browser. it rebuilds the spike buffer from the spikes field and computes keccak256 likewise. it compares each with the frameHash and spikeDigest fields of the Act event for fly act n. both must match for the receipt to be marked verified. a fetch failure leaves the mark blank and is retried on the next poll, up to five times, after which the row is marked mismatch, because a file that cannot be produced is a file that cannot be checked. a reader who wants to go further reruns the model: load circuit.json, load the sixteen frames, run the step procedure, and compare the spike array. the rig's implementation is the reference and is published with the site's source.

the arena constants

TOKEN         immutable                                   the token whose fees feed the arena and whose supply the burns reduce
MARKET        immutable                                   the pons market for the token, the only destination coin can be sent to
FEES          immutable                                   the pons contract holding accrued creator fees
FLY           immutable                                   the fly key, the only address that may call flyAct
DEPLOY_BLOCK  immutable                                   the block of deployment
DEAD          0x000000000000000000000000000000000000dEaD  where bought tokens go
EPOCH         128                                         blocks between acts of one arm
CAP_DIV       16                                          an act may spend at most budget / CAP_DIV
SWEEP_EPOCHS  256                                         epochs of fly silence before sweep is allowed

the arena line by line

collect: record the balance; call the fee vault's claim for the token; let got be the balance increase; add got / 2 to flyBudget and got minus got / 2 to controlBudget; emit Collect. flyAct(kind, size, frameHash, spikeDigest): require the caller is FLY; require kind is 0 or 1 and size is 1 through 8; require block.number minus lastFlyBlock is at least EPOCH; set lastFlyBlock to block.number; increment flyActs; if kind is 0, emit Act with zero spend and zero burned and return; otherwise let cap be flyBudget / CAP_DIV, spend be cap times size / 8; require spend greater than zero; subtract spend from flyBudget; buy and burn as below; add to flySpent and flyBurned; emit Act. controlAct(): require block.number minus lastControlBlock is at least EPOCH; set lastControlBlock; increment controlActs; spend is controlBudget / CAP_DIV; require spend greater than zero; subtract; buy and burn; add to controlSpent and controlBurned; emit Act with arm 1, kind 1, size 8, zero hashes. sweep(): require block.number minus lastFlyBlock is at least SWEEP_EPOCHS times EPOCH; require flyBudget greater than zero; move flyBudget to controlBudget; increment sweeps; add to swept; emit Sweep. buy and burn: record the token balance; call the market's buy with the spend as value and zero minimum output; the increase in token balance is burned; transfer it to DEAD and require true. state is fully written before any external call in every function, so reentry finds nothing to take.

note that lastFlyBlock is set to the current block, not advanced by a multiple of EPOCH as a metronome would do, because the fly's cadence is at least 128 blocks rather than exactly 128; the rig may be late, and a late act simply starts the next window later. the metronome uses the same rule for symmetry: it too may be late, and late is not a failure, only a delay.

the two arms and the measure

the measure for each arm is burned over spent, tokens per coin, computed from storage. it is rendered to two decimals and only when spent is greater than zero. it is not a rate of return and is not annualized; it is how many tokens each coin bought, and a higher number means the arm bought at lower average prices. because both arms draw on the same fee stream, spend under the same cap, and buy on the same market, the only systematic difference between them is that one arm's acts are conditional on the fly's turn. a difference in the measure that persists over many acts is therefore evidence about the fly's seeing, and its absence is evidence too. the page prints both numbers and nothing else about them.

the sweep

the sweep condition is block.number minus lastFlyBlock at least 32,768 blocks. a rest counts as an act, so a rig that is running but seeing nothing worth biting keeps its budget. only a rig that has stopped calling loses it. the sweep moves the entire fly budget at once, emits a receipt, and does not touch lastFlyBlock, so a rig that returns can act on the next epoch with whatever has been collected since. sweeps are counted and summed so that the history of silence is on the record.

the rig

the rig is a supabase project with one schedule and four edge functions, described so that anyone can run their own against the same contract and compare receipts.

tables: circuit_types (type, side, count, source url, imported at); bouts (index, epoch first block, sample blocks, prices, phases, hs left, hs right, turn, kind, size, frame hash, spike digest, tx hash, status, log); setup (stage, status, detail, updated at). storage bucket fly, public read, holding circuit.json and frames/n.json.

import-circuit: runs once, triggered by the first page load through a public function that only starts it if setup shows it has not run. it queries neuprint for the listed types and their synapses with the NEUPRINT_TOKEN secret, derives the descending set, computes the lattice assignment from the column table of the reiser lab release (fetched from its public github pages) with the fallback ordering by soma position, writes circuit.json, fills circuit_types, and records its progress stage by stage in setup. it is self chaining: each invocation does one stage and invokes the next, so no single call exceeds the function time limit. the cheap stages, writing the type list and the published counts, run first, so circuit_types has rows within seconds even if the synapse stages take minutes.

run-bout: on a pg_cron schedule every minute; it reads the current block; if the block is at least lastFlyBlock plus 128 and no bout is in progress, it starts one: samples prices, renders frames, runs the model in a worker bounded by the function's cpu budget, and writes the bout row as it goes. if the model cannot finish within the budget it records status timeout, writes the frame file with the frames and an empty spike array, and does not sign an act; the fly rests by omission and the log says why. when the model finishes it writes the frame file, hashes it, and marks the bout ready.

sign-act: picks up bouts marked ready, signs flyAct(kind, size, frameHash, spikeDigest) with the FLY_KEY secret through the rpc, waits for the receipt, records the tx hash and marks sent. it retries a failed send three times and then marks failed with the error.

read-status: public, read only; returns the setup and latest bouts rows so that the docs page can show the rig's own view of itself in the rig status table below. the site never writes to any of these; the functions do.

secrets: NEUPRINT_TOKEN, FLY_KEY, RPC_URL. the fly key is generated once, its address is passed to the arena's constructor, and it holds only enough of the native coin to pay gas for acts; it holds no tokens and can hold no fee revenue, because the arena never sends coin to it.

import stage
import status
types imported
last bout index
last bout status
last bout log line
bouts total
bouts sent
bouts timed out
bouts failed

reading the state from a node

eth_blockNumber, eth_getBlockByNumber(latest)     chain     current block, timestamp
eth_getBlockByNumber(latest − 256)                chain     observed interval
reserve, flyBudget, controlBudget                  arena     budgets
lastFlyBlock, lastControlBlock                     arena     cadence, epochs since the fly acted
flyActs, controlActs, sweeps, swept                arena     counts
flySpent, flyBurned, controlSpent, controlBurned   arena     the measure
FLY, EPOCH, CAP_DIV, SWEEP_EPOCHS, capNow          arena     constants and caps
totalSupply, decimals, balanceOf(dead)             token     supply and burn
eth_getLogs(Act), eth_getLogs(Sweep)               arena     the tape
GET circuit.json, GET frames/n.json                store     verification, the last frame

reproducing every figure

fig. 1 is the 28 row layout with the widths listed; nothing in it depends on data. fig. 2 is sixteen strips of a grating with Λ of 8 at phases k times π over 4. fig. 3 is the pathway diagram with the boxes and connections listed; the cell types are the release's names. fig. 4 is a schematic of one leaky integrate and fire cell with the jump, leak, threshold, reset and refractory hold drawn at 10 pixels per millisecond. fig. 5 is the arena's storage at one cell per byte. fig. 6 is a ruler of 256 epochs with the sweep at its end. the last frame block is fig. 1 filled from a real frame file; the only figure on the site that changes with data.

invariants

one: flyBudget plus controlBudget plus flySpent plus controlSpent equals the sum of all Collect amounts. two: the arena's coin balance is at least flyBudget plus controlBudget, with equality absent forced transfers. three: flySpent is the sum of spend over fly Act events and flyBurned the sum of burned; likewise for the metronome. four: the dead address token balance is at least flyBurned plus controlBurned. five: for every fly bite, spend equals (flyBudgetBefore / 16) times size / 8 with flyBudgetBefore reconstructed from the previous receipt and the Collects between. six: for every metronome act, spend equals controlBudgetBefore / 16. seven: consecutive acts of one arm are at least 128 blocks apart. eight: every Sweep is at least 32,768 blocks after the previous fly Act. nine: for every verified fly receipt, rerunning the model over its frames yields its spike array.

failure modes

the rig stops: rests stop, the epochs since the fly acted climb, sweep becomes callable at 256 epochs, the metronome keeps burning. the rpc lies to the rig: wrong prices, wrong frames, but published frames, and a reader comparing against the market's reserves at the sample blocks sees it. neuprint unavailable at import: the setup stage says so, circuit_types shows only the published rows, no bout can run, the fly arm rests by omission until the import succeeds, the metronome runs regardless. the model times out: the bout is recorded as timed out with its frames, no act is signed, the log says so. pons reverts on buy: the act reverts, nothing changes. the burn transfer returns false: the act reverts and the tokens return through the revert. the frame store is down: receipts cannot be verified until it returns; the marks stay blank and then, after five failed fetches, red. a searcher sandwiches an act: bounded by the cap, a sixteenth of a budget, and by the size for the fly. the fly key is stolen: the thief can call flyAct under the same cap and cadence and can do nothing else; the receipts of a thief's acts carry whatever hashes the thief chose, and if the files do not match, the marks go red.

what the machine cannot do

the arena cannot pay anyone. it cannot send coin anywhere but the market or tokens anywhere but the dead address. it cannot change its cap, its cadence, its sweep, its split, its token, its market, its fee vault or its fly key. the fly key cannot act more than once per 128 blocks, cannot spend above the cap, cannot withdraw, cannot redirect. the rig cannot invent a neuron or a connection. the site cannot write.

deployment

generate the fly key; fund it with gas. deploy the arena with the token, its pons market, the pons fee vault, and the fly key's address. set the token's creator fee recipient to the arena through pons. verify the source on the explorer. create the supabase project, set the three secrets, create the tables, the bucket and the schedule, deploy the four functions. fill the site's config with the arena, token and market addresses, the deployment block, the rpc url, the explorer base, and the frame store url. load the site once to trigger the import. the published rows of the types table, all six figures, every paragraph, the equations and the parameter tables render before any of this; the slots fill as each piece comes online.

source

the complete source of the arena, as deployed; compare to the verified source on the explorer.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

interface IERC20 {
    function balanceOf(address a) external view returns (uint256);
    function transfer(address to, uint256 amount) external returns (bool);
}

interface IPonsFees {
    function claim(address token) external;
}

interface IPonsMarket {
    function buy(address token, uint256 minOut) external payable returns (uint256);
}

contract Arena {
    address public immutable TOKEN;
    address public immutable MARKET;
    address public immutable FEES;
    address public immutable FLY;
    uint64  public immutable DEPLOY_BLOCK;

    address public constant DEAD = 0x000000000000000000000000000000000000dEaD;
    uint64  public constant EPOCH = 128;
    uint64  public constant CAP_DIV = 16;
    uint64  public constant SWEEP_EPOCHS = 256;

    uint64  public lastFlyBlock;
    uint64  public lastControlBlock;
    uint64  public flyActs;
    uint64  public controlActs;
    uint64  public sweeps;
    uint256 public flyBudget;
    uint256 public controlBudget;
    uint256 public flySpent;
    uint256 public flyBurned;
    uint256 public controlSpent;
    uint256 public controlBurned;
    uint256 public swept;

    event Act(uint8 indexed arm, uint64 indexed index, uint64 blockNumber, uint8 kind, uint8 size, uint256 spend, uint256 burned, bytes32 frameHash, bytes32 spikeDigest, uint256 budgetAfter);
    event Collect(uint256 amount, uint256 flyAfter, uint256 controlAfter);
    event Sweep(uint64 indexed index, uint64 blockNumber, uint256 amount, uint256 controlAfter);

    constructor(address token, address market, address fees, address fly) {
        TOKEN = token;
        MARKET = market;
        FEES = fees;
        FLY = fly;
        DEPLOY_BLOCK = uint64(block.number);
        lastFlyBlock = uint64(block.number);
        lastControlBlock = uint64(block.number);
    }

    function reserve() external view returns (uint256) {
        return flyBudget + controlBudget;
    }

    function capNow() external view returns (uint256 flyCap, uint256 controlCap) {
        flyCap = flyBudget / CAP_DIV;
        controlCap = controlBudget / CAP_DIV;
    }

    function collect() external {
        uint256 before = address(this).balance;
        IPonsFees(FEES).claim(TOKEN);
        uint256 got = address(this).balance - before;
        uint256 half = got / 2;
        flyBudget += half;
        controlBudget += got - half;
        emit Collect(got, flyBudget, controlBudget);
    }

    function flyAct(uint8 kind, uint8 size, bytes32 frameHash, bytes32 spikeDigest) external {
        require(msg.sender == FLY, "not the fly");
        require(kind <= 1, "bad kind");
        require(size >= 1 && size <= 8, "bad size");
        require(block.number - lastFlyBlock >= EPOCH, "epoch open");
        lastFlyBlock = uint64(block.number);
        flyActs += 1;
        if (kind == 0) {
            emit Act(0, flyActs, uint64(block.number), 0, size, 0, 0, frameHash, spikeDigest, flyBudget);
            return;
        }
        uint256 cap = flyBudget / CAP_DIV;
        uint256 spend = cap * size / 8;
        require(spend > 0, "nothing to spend");
        flyBudget -= spend;
        uint256 got = _buyAndBurn(spend);
        flySpent += spend;
        flyBurned += got;
        emit Act(0, flyActs, uint64(block.number), 1, size, spend, got, frameHash, spikeDigest, flyBudget);
    }

    function controlAct() external {
        require(block.number - lastControlBlock >= EPOCH, "epoch open");
        lastControlBlock = uint64(block.number);
        controlActs += 1;
        uint256 spend = controlBudget / CAP_DIV;
        require(spend > 0, "nothing to spend");
        controlBudget -= spend;
        uint256 got = _buyAndBurn(spend);
        controlSpent += spend;
        controlBurned += got;
        emit Act(1, controlActs, uint64(block.number), 1, 8, spend, got, bytes32(0), bytes32(0), controlBudget);
    }

    function sweep() external {
        require(block.number - lastFlyBlock >= SWEEP_EPOCHS * EPOCH, "fly is awake");
        uint256 amount = flyBudget;
        require(amount > 0, "nothing to sweep");
        flyBudget = 0;
        controlBudget += amount;
        sweeps += 1;
        swept += amount;
        emit Sweep(sweeps, uint64(block.number), amount, controlBudget);
    }

    function _buyAndBurn(uint256 spend) internal returns (uint256 got) {
        uint256 before = IERC20(TOKEN).balanceOf(address(this));
        IPonsMarket(MARKET).buy{value: spend}(TOKEN, 0);
        got = IERC20(TOKEN).balanceOf(address(this)) - before;
        require(IERC20(TOKEN).transfer(DEAD, got), "burn failed");
    }
}

the two pons interfaces are the adapter, the only code written against another program. before deployment they are matched against the pons fee vault and market the token actually uses; if the selectors differ, they and only they change.

glossary

arena: the contract. fly: the male cns connectome run as a model. fly key: the one address that may call flyAct. metronome: the control arm. arm: fly or metronome. act: one call of flyAct or controlAct. bite: an act that buys and burns. rest: a fly act that spends nothing. size: one to eight, the fraction of the cap a bite spends. cap: budget over 16. epoch: 128 blocks. sweep: the transfer of a silent fly's budget to the metronome after 256 epochs. lattice: the 892 position layout of the right eye's L1 columns. frame: 892 luminance bytes. grating: the drifting sinusoid drawn on the lattice. phase: the grating's offset, driven by log return. horizontal system: HSN, HSE and HSS, the cells the turn is read from. turn: right HS spikes minus left HS spikes. frame hash: keccak256 of sixteen frames. spike digest: keccak256 of every neuron's spike count. circuit file: the imported wiring, hashed and published. rig: the off chain process that renders, simulates and signs. receipt: an Act or Sweep event. tape: the list of receipts. verified: both hashes of a receipt match its published file.