# bittensor-talk

Slide deck for Jacob Steeves' Bittensor keynote, "A mind outside the state"
(Exploit Conference, Montreal, 28 September 2026). A small static web deck built
with Vite and TypeScript. No framework, no backend.

Live: https://bittensor-talk.pages.dev

## Use the deck

- Arrow keys, space, Enter, or PageDown/PageUp move between slides. Click the right
  side of a slide to go forward, the left side to go back. Swipe on a phone.
- Each slide has its own URL: `/#/12` opens slide 12.
- Press `s` to open the speaker-notes view. It shows the notes, the "on screen"
  description, the `VERIFY` badge for slides whose numbers must be re-checked, and
  the `JACOB` badge for slides with a decision or number only the speaker can supply
  (each is highlighted inline in the notes as `[JACOB …]`).
- Press `f` for fullscreen, `Home`/`End` to jump to the first or last slide.

## Edit content

The words live in `content/slides.md` (one `##` heading per slide, with an
**On screen** line and **Notes** bullets; the first note carries the minute mark).
The layout of each slide (theme and the structured hero content) lives in the
`LAYOUTS` table in `scripts/generate-slides.mjs`.

Every chart is drawn from `content/data.json`. Each series carries its source and the
date it was pulled (`asOf`). To refresh the numbers before the talk, edit that one file,
run `npm run slides`, and check slides 1 to 6, 9, 10, 13, 14, 23, 24, 26, 27 and 29. The charts are
inline SVG built in `src/figures.ts`; there is no chart library.

Slides 1 and 2 are the opening added on 23 September: the five-year trend chart
(`data.json → trend`, four series on a log axis, every point with its block number on the
public archive node) and the row of eight subnet cards (`data.json → library`, names and
netuids read from the chain). Slides 3 to 5 are the growth trio added 24 September, in the
order compute, inference, data: Lium's year (`data.json → growthLium`: dollars billed and
GPUs online from Lium's public Grafana, burns from the chain); tokens a day across Chutes,
Engy and SayGM (`data.json → growthInference`: chutes.ai/app/research, Engy's signed ledger,
SayGM's posts); and the data layer (`data.json → growthData`: four panels, Hippius SN75 bytes
stored, NOVA SN68 molecules in the open archive, Data Universe SN13 rows, Beam SN105 largest
transfer, each on its own scale). Slide 6, "Twelve markets", is the metrics grid added the same
day: the twelve strongest rising series across the subnets (`data.json → metricsGrid`, one panel
each in the Data slide's form, four across and three down at 16:9, two across on a phone; each
panel carries its source, and a point carries a source only where it differs). Everything else
in the deck moved down by six from its 21 September number (seven from slide 11 on, after the
incentives slide). Method and caveats for the trio and the grid: `docs/growth-slides.md` in the
project store; the grid's series were graded in `docs/metrics-gallery.md`.

`npm run slides` turns the Markdown and the data file into `src/slides.json`, which is
the single file the site renders. `npm run dev` and `npm run build` run this step for
you. The plan for each figure (purpose, series, chart type, annotation) is in the
project store at `docs/charts-plan.md`.

## Run locally

```bash
npm install
npm run dev        # http://127.0.0.1:4718
```

## Deploy

The site deploys to Cloudflare Pages (project `bittensor-talk`, see `wrangler.jsonc`).

Set two environment variables first: `CLOUDFLARE_API_TOKEN` (an account token with
Pages write access) and `CLOUDFLARE_ACCOUNT_ID`. Then run:

```bash
npm run deploy
```

Note for this bundle: `dist/` here was built with `vite build --base=./` (relative
asset paths) so the deck opens from a subfolder or from a local disk. The Pages
deploy uses the default absolute base.

`npm run deploy` builds the site and uploads `dist/` with Wrangler. Nothing secret
is stored in this repository.
