AI vs. Shrimp

How likely Hinton, Chalmers, Seth, Pinker and 29 others think today's LLMs are to be conscious, read from their own words, with quotes and sources.

---
format: typebulb/v1
name: AI vs. Shrimp
---

**code.tsx**

```tsx
import React, { useEffect, useRef, useState } from "react"
import { createRoot } from "react-dom/client"
import * as THREE from "three"
import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer"
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass"
import { UnrealBloomPass } from "three/examples/jsm/postprocessing/UnrealBloomPass"

// ── data ──────────────────────────────────────────────────────────────────

type Src = { label: string; url: string }
// a reading of how likely the person thinks today's LLMs are conscious: [lowest, most likely, highest], each 0..1.
// A null most-likely value means their words give a range but point nowhere inside it.
type Dist = [number, number | null, number]
type Person = {
  name: string; who: string
  year: number                        // when the evidence for the placement is from
  dist: Dist
  level: Dist                         // if conscious, how conscious: [lo, most likely, hi] in rungs (1 = silkworm … 9 = human)
  p?: [number, number]                // a probability they stated themselves, where there is one
  pTarget?: string                    // what that stated probability was for, when it isn't consciousness
  view: string                        // their theory of consciousness (see the notes file for the sources)
  viewInferred?: boolean              // the view is the compiler's reading, not stated in their own words
  ai?: boolean                        // the row is an AI model's view of itself, not a person's
  basis: string[]
  quote?: string; note?: string; src: Src[]
}
// A rung from Rethink Priorities' samples (tools/ladder.py), or a value fixed by definition (def: Rock, Human).
// psent: the mean chance the animal is sentient. ifSentient: the median welfare range if it is. q: psent times the
// 0th–100th percentiles of the welfare range if sentient, which draw the hover distribution.
// neurons: the animal's neuron count as a share of a human's, as RP's neuron-count model uses it
type Rp = { psent?: number; ifSentient?: number; def?: number; note?: string; q?: number[]; neurons: number }
type Data = { rungs: string[]; icons: string[]; rp: Rp[]; people: Person[] }

const d = tb.json<Data>(0)
const max = d.rungs.length - 1
const pct = (x: number) => (x / max) * 100
const icon = (code: string) => `https://cdn.jsdelivr.net/gh/jdecked/[email protected]/assets/svg/${code}.svg`

// ── colour: position on the ladder, grey toward Rock, blue mid-way, red toward Human ──

const colorAt = (x: number) => {
  const t = Math.min(1, Math.max(0, x / max))
  return t <= 0.5
    ? `color-mix(in oklab, var(--mid) ${Math.round(t * 200)}%, var(--cold))`
    : `color-mix(in oklab, var(--hot) ${Math.round(Math.min(1, (t - 0.5) / 0.35) * 100)}%, var(--mid))`   // full red from about Pig up
}
// text versions are pulled toward the text colour so grey stays legible
const legible = (c: string) => `color-mix(in oklab, ${c} 60%, var(--fg))`

// ── the ladder's scale ────────────────────────────────────────────────────

// Each rung's welfare value: its chance of sentience times its median welfare range if sentient, the same footing as
// an LLM row (a chance of consciousness times a level priced if sentient); or its value fixed by definition
const rungVal = d.rp.map(r => r.def ?? (r.psent ?? 0) * (r.ifSentient ?? 0))
// a value fixed by definition (Rock, Human) is just a distribution with all its mass at that value
for (const r of d.rp) if (r.def !== undefined) r.q ??= Array(101).fill(r.def)
// A ladder position as a welfare value: a smooth monotone curve through the rungs (cubic Hermite with Fritsch–Butland
// slopes), not straight segments. Straight segments change slope at every rung, so a smooth spread of values drawn on
// the ladder jumped at each rung where the gap to the next animal widens: a false spike just past the silkworm, the fish.
const rungSlope = rungVal.map((_, i) => {
  const l = i > 0 ? rungVal[i] - rungVal[i - 1] : undefined, r = i < max ? rungVal[i + 1] - rungVal[i] : undefined
  if (l === undefined) return r!
  if (r === undefined) return l
  return l * r > 0 ? (2 * l * r) / (l + r) : 0
})
const fromRung = (x: number) => {
  const i = Math.min(max - 1, Math.max(0, Math.floor(x))), t = Math.min(1, Math.max(0, x - i))
  const y0 = rungVal[i], y1 = rungVal[i + 1], m0 = rungSlope[i], m1 = rungSlope[i + 1]
  return (2 * t ** 3 - 3 * t ** 2 + 1) * y0 + (t ** 3 - 2 * t ** 2 + t) * m0 + (-2 * t ** 3 + 3 * t ** 2) * y1 + (t ** 3 - t ** 2) * m1
}
// a welfare value as a position on the ladder, fromRung's inverse, stopping at Rock and Human
const toRung = (v: number) => {
  if (v <= rungVal[0]) return 0
  if (v >= rungVal[max]) return max
  let lo = 0, hi = max
  for (let k = 0; k < 40; k++) { const mid = (lo + hi) / 2; if (fromRung(mid) < v) lo = mid; else hi = mid }
  return (lo + hi) / 2
}

// ── readings ──────────────────────────────────────────────────────────────

// Near 100% reads ">99%": never a rounded-up certain 100%, and no false precision like 99.5% to quibble with
const percent = (x: number) => x > 0.99 && x < 1 ? ">99%" : `${+(x * 100).toFixed(x < 0.1 ? 1 : 0)}%`
// the PERT mean, or for a range with no most-likely value the mean of its log-flat curve (see pert)
const mean = (dist: Dist) => {
  const [a, m, b] = dist
  if (m !== null) return (a + 4 * m + b) / 6
  let s = 0, w = 0
  for (let k = 0; k < 2000; k++) { const x = a + ((b - a) * (k + 0.5)) / 2000, f = pert(dist, x, true); s += f * x; w += f }
  return s / w
}
// P: the chance, on the person's reading, that today's LLMs are conscious at all
const chance = (p: Person) => mean(p.dist)
// the even trade: the ladder position of the LLM's expected welfare range (see the rows section); rows sort by it
const expected = (p: Person) => toRung(worth(p))
const LEVEL_DEFAULT = (l: Dist) => l[0] === 1 && l[1] === null && l[2] === max   // no view on how conscious
const levelText = (l: Dist) => {
  // a level below the silkworm still names the silkworm: "if conscious" can't land on the rock
  const name = (x: number) => d.rungs[Math.max(1, Math.round(x))].toLowerCase()
  const a = name(l[0]), b = name(l[2])
  return a === b ? a : `${a} to ${b}`
}
// Below the silkworm, the simplest animal on the ladder, no animal is an even trade: the row shows only its gray bar
const belowLadder = (p: Person) => expected(p) < 1
const placeText = (p: Person) =>
  `${percent(chance(p))} chance · ${belowLadder(p) ? "<" : "≈"} ${d.rungs[Math.max(1, Math.round(expected(p)))].toLowerCase()}`

// ── theories of consciousness ─────────────────────────────────────────────

// The mark beside a name: the person's theory of consciousness, by the name its holders use for it. Each theory has
// its own shape; colour groups them by family, so illusionism shares functionalism's colour (both say what matters is
// what a system does) and panpsychism shares IIT's (both rest on the physical system, not the computation). Views
// that fit none (religious, mysterian, Hoel's continual learning, Shanahan's refusal of the question) and unclear
// ones get no mark, and a view that's only the compiler's reading is drawn hollow.
type MarkShape = "square" | "plus" | "triangle" | "diamond" | "pentagon" | "circle"
type Family = "func" | "bio" | "phys" | "agn"
const VIEW_MARKS: { view: string; shape: MarkShape; family: Family; label: string }[] = [
  { view: "functionalism", shape: "square", family: "func", label: "Computational functionalism" },
  { view: "illusionism", shape: "plus", family: "func", label: "Illusionism" },
  { view: "biological", shape: "triangle", family: "bio", label: "Biological naturalism" },
  { view: "iit", shape: "diamond", family: "phys", label: "Integrated information theory" },
  { view: "panpsychist", shape: "pentagon", family: "phys", label: "Panpsychism" },
  { view: "agnostic", shape: "circle", family: "agn", label: "Agnostic" },
]
const markOf = (p: Person) => VIEW_MARKS.find(m => m.view === p.view)

// an unmarked row still takes the mark's width, so every name starts at the same x
function Glyph({ shape, family, hollow }: { shape?: MarkShape; family?: Family; hollow?: boolean }) {
  return (
    <svg className={`vm ${family ?? ""}${hollow ? " hollow" : ""}`} viewBox="0 0 10 10" aria-hidden="true">
      {shape === "square" && <rect x="1" y="1" width="8" height="8" />}
      {shape === "plus" && <path d="M3.5,0.6 H6.5 V3.5 H9.4 V6.5 H6.5 V9.4 H3.5 V6.5 H0.6 V3.5 H3.5 Z" />}
      {shape === "triangle" && <path d="M5,0.6 L9.5,9.2 L0.5,9.2 Z" />}
      {shape === "diamond" && <path d="M5,0.3 L9.7,5 L5,9.7 L0.3,5 Z" />}
      {shape === "pentagon" && <path d="M5,0.5 L9.5,3.8 L7.8,9.2 L2.2,9.2 L0.5,3.8 Z" />}
      {shape === "circle" && <circle cx="5" cy="5" r="4.3" />}
    </svg>
  )
}

function ViewKey() {
  return (
    <p className="view-key">
      {VIEW_MARKS.map(m => <span key={m.view}><Glyph shape={m.shape} family={m.family} />{m.label}</span>)}
      <span><Glyph shape="square" family="func" hollow />Hollow: the compiler’s reading, not their words</span>
      <span>No mark: another view, or none stated</span>
    </p>
  )
}

// ── distributions on the ladder ───────────────────────────────────────────

// Every distribution, a person's row and a rung's on hover, is drawn one way: its mass in bins five per rung, scaled
// so the tallest fills the height, linear between bin centres. A point mass (Rock and Human by definition, RP's pile
// past Human) is a block one bin wide with upright sides, never a slope.
const BINS = 45, W = max / BINS
type Shape = { bins: number[]; lo: number; hi: number }   // spread mass per bin, plus the point masses at Rock and Human
const xs = Array.from({ length: 201 }, (_, k) => (k / 200) * max)
// the outline's x positions; each block's upright side is two points at one x. One point count for every shape, so
// the colour bar's morph always has matching paths
const PTS = [
  ...xs.filter(x => x < W).map(x => ({ x, lo: true, hi: false })),
  { x: W, lo: true, hi: false }, { x: W, lo: false, hi: false },
  ...xs.filter(x => x > W && x < max - W).map(x => ({ x, lo: false, hi: false })),
  { x: max - W, lo: false, hi: false }, { x: max - W, lo: false, hi: true },
  ...xs.filter(x => x > max - W).map(x => ({ x, lo: false, hi: true })),
]

// a binned distribution's height at x, linear between bin centres
const spreadAt = (bins: number[], x: number) => {
  const t = Math.min(BINS - 1, Math.max(0, (x / max) * BINS - 0.5)), j = Math.floor(t)
  return bins[j] + (bins[Math.min(BINS - 1, j + 1)] - bins[j]) * (t - j)
}
// Heights 0..1 at each outline point. With clip, a lone spike more than twice the next-highest bin (RP's neuron-count
// component near zero) is clipped to full height, so the rest of the shape stays readable.
function heights({ bins, lo, hi }: Shape, clip = false) {
  const total = bins.map((m, j) => m + (j === 0 ? lo : 0) + (j === BINS - 1 ? hi : 0))
  const sorted = [...total].sort((a, b) => b - a)
  const scale = (clip && sorted[1] > 0 && sorted[0] > 2 * sorted[1] ? sorted[1] * 1.15 : sorted[0]) || 1
  return PTS.map(p => Math.min(1, (spreadAt(bins, p.x) + (p.lo ? lo : 0) + (p.hi ? hi : 0)) / scale))
}
// "x,y" for each outline point, between a baseline and a top in the 0..1000 × 0..100 viewBox
const outline = (h: number[], base: number, top: number) =>
  PTS.map((p, k) => `${((p.x / max) * 1000).toFixed(1)},${(base - h[k] * (base - top)).toFixed(1)}`)

// ── the even trade ────────────────────────────────────────────────────────

// Forced to choose between torturing an LLM and torturing an animal, which animal is the even trade? On expected value
// an LLM's welfare range is P, the chance it's conscious, times E[w | conscious], its welfare range if it is: the level
// reading averaged over RP's medians. A row's curve is the distribution of that product on the ladder, with P drawn
// from the reading's low / likely / high, and its tick marks the mean. Both readings are a PERT curve (the beta
// distribution estimators fit through low / likely / high) when there is a most likely value, else flat with soft
// shoulders.
const GRID = 361, DX = max / (GRID - 1)
// With no most-likely value, a range is flat with soft shoulders: flat in log P for a chance (logFlat), so every order
// of magnitude in "somewhere between 1% and 70%" counts the same and the reading doesn't sit at the midpoint; flat on
// the ladder for a level.
function pert([a, m, b]: Dist, x: number, logFlat = false) {   // unnormalised
  if (x < a || x > b) return 0
  const t = (x - a) / (b - a)
  if (m === null) {
    const ss = (u: number) => { const v = Math.min(1, u / 0.12); return v * v * (3 - 2 * v) }
    if (!logFlat) return Math.min(ss(t), ss(1 - t))
    const lo = Math.max(a, 1e-4)
    if (x < lo) return 0
    const u = Math.log(x / lo) / Math.log(b / lo)
    return Math.min(ss(u), ss(1 - u)) / x
  }
  const mm = Math.min(b, Math.max(a, m))
  const al = 1 + (4 * (mm - a)) / (b - a), be = 1 + (4 * (b - mm)) / (b - a)
  return t ** (al - 1) * (1 - t) ** (be - 1)
}
function levelDensity(l: Dist) {
  const g = Array.from({ length: GRID }, (_, k) => pert(l, k * DX))
  const area = g.reduce((s, v) => s + v, 0) * DX
  return g.map(v => v / area)
}
// "If conscious, as conscious as a shrimp" is priced in the shrimp's welfare range if it is sentient. The ladder's own
// values (rungVal) are RP's headline figures, which already multiply in each animal's chance of being sentient, so
// pricing the level in them would discount the LLM by the shrimp's doubt on top of its own.
const ifSentientVal = d.rp.map(r => r.ifSentient ?? r.def ?? 0)
const levelValue = (x: number) => {
  const i = Math.min(max - 1, Math.floor(x))
  return ifSentientVal[i] + (ifSentientVal[i + 1] - ifSentientVal[i]) * (x - i)
}
// E[w | conscious] and the expected welfare range, each as a share of a human's
const ifConscious = (p: Person) => levelDensity(p.level).reduce((s, v, k) => s + v * DX * levelValue(k * DX), 0)
const worth = (p: Person) => chance(p) * ifConscious(p)
function tradeShape(p: Person): Shape {
  // P's CDF on a fine grid; a ladder bin's mass is the chance that P × E[w | conscious] lands in it
  const [a, , b] = p.dist, N = 1000, cdf = [0]
  for (let k = 1; k <= N; k++) cdf.push(cdf[k - 1] + pert(p.dist, a + ((b - a) * (k - 0.5)) / N, true))
  const F = (P: number) => {
    const u = Math.min(N, Math.max(0, ((P - a) / (b - a)) * N)), k = Math.floor(u)
    return (cdf[k] + (cdf[Math.min(N, k + 1)] - cdf[k]) * (u - k)) / cdf[N]
  }
  const Ew = ifConscious(p)
  const bins = Array.from({ length: BINS }, (_, j) => F(fromRung((j + 1) * W) / Ew) - F(fromRung(j * W) / Ew))
  return { bins, lo: 0, hi: 0 }
}

function Curve({ p }: { p: Person }) {
  const h = heights(tradeShape(p))
  // the rock itself, "not conscious at all", is the gray bar's; the curve rises from the baseline there
  h[0] = 0
  const pts = outline(h, 98, 6)
  // the edge skips stretches lying flat on the baseline, so no row carries a dark rule along its foot
  const on = (k: number) => [k - 1, k, k + 1].some(i => (h[i] ?? 0) > 0.005)
  const edge = pts.map((s, k) => on(k) ? `${k > 0 && on(k - 1) ? "L" : "M"}${s}` : "").join(" ")
  return (
    <svg className="curve" viewBox="0 0 1000 100" preserveAspectRatio="none" aria-hidden="true">
      <path className="fill" d={`M0,98 L${pts.join(" L")} L1000,98 Z`} />
      <path className="edge" d={edge} vectorEffect="non-scaling-stroke" />
    </svg>
  )
}
// the ladder's colours laid along the scale; every distribution fills with it, so colour always means position
function InkDefs() {
  return (
    <svg width="0" height="0" style={{ position: "absolute" }} aria-hidden="true">
      <defs>
        <linearGradient id="ladder-fill" gradientUnits="userSpaceOnUse" x1="0" x2="1000" y1="0" y2="0">
          {[0, 0.25, 0.5, 0.75, 1].map(t => <stop key={t} offset={t} style={{ stopColor: colorAt(t * max) }} />)}
        </linearGradient>
      </defs>
    </svg>
  )
}

// ── the colour bar and its distributions ──────────────────────────────────

// The bar's top edge is flat; hovering an animal raises it into that animal's distribution, and it flattens back on
// leave. The shape is RP's own: the percentiles of their simulation samples, moved onto the ladder's scale and binned.
const BAR = (100 * 8) / 52   // the bar's thickness, in viewBox units of the 52px-tall drawing

// Share of the distribution in each ladder bin; samples at zero are a point mass at Rock, and anything past Human
// piles into a point mass at Human
function rpShape(q: number[]): Shape {
  const X = q.map(toRung)
  const F = (x: number) => {   // CDF on the ladder, interpolating within each 1% step
    if (x <= X[0]) return 0
    for (let k = 0; k < 100; k++) if (x <= X[k + 1]) return (k + (X[k + 1] > X[k] ? (x - X[k]) / (X[k + 1] - X[k]) : 1)) / 100
    return 1
  }
  const bins = Array.from({ length: BINS }, (_, j) => F(((j + 1) / BINS) * max) - F((j / BINS) * max))
  const lo = X.slice(1).filter(x => x <= 0).length / 100
  bins[0] -= lo
  return { bins, lo, hi: 1 - F(max) }
}

function barShape(q?: number[]) {
  const h = q ? heights(rpShape(q), true) : PTS.map(() => 0)
  const pts = outline(h, 100 - BAR, 3)
  return { area: `M0,100 L${pts.join(" L")} L1000,100 Z`, edge: `M${pts.join(" L")}` }
}

function ScaleBar({ hover }: { hover: number | null }) {
  // Rock and Human are fixed by definition, so they have no spread to draw, only their marker; the rock's steps left
  // with its label across the scale's break
  const r = hover === null || d.rp[hover].def !== undefined ? undefined : d.rp[hover]
  const { area, edge } = barShape(r?.q)
  return (
    <span className="track scalebar">
      <svg className="dist" viewBox="0 0 1000 100" preserveAspectRatio="none" aria-hidden="true">
        {/* the CSS `d` property animates the morph where supported; the attribute is the fallback */}
        <path d={area} style={{ d: `path("${area}")`, fill: "url(#ladder-fill)" } as React.CSSProperties} />
        <path d={edge} className={r?.q ? "edge on" : "edge"}
          style={{ d: `path("${edge}")`, fill: "none", stroke: "var(--fg)", strokeWidth: 1.5 } as React.CSSProperties}
          vectorEffect="non-scaling-stroke" />
      </svg>
      {r && (r.q?.[95] ?? 0) > 1 && <i className="sb-cap" style={{ left: "100%" }} />}
      {hover !== null && <i className="sb-med" style={{ left: `${pct(hover)}%` }} />}
    </span>
  )
}

// ── rows ──────────────────────────────────────────────────────────────────

function Track({ children }: { children?: React.ReactNode }) {
  return (
    <span className="track" aria-hidden="true">
      {d.rungs.map((_, i) => <i key={i} style={{ left: `${pct(i)}%` }} />)}
      {children}
    </span>
  )
}

function Sources({ src }: { src: Src[] }) {
  return (
    <p className="sources">
      {src.map((s, i) => <a key={i} href={s.url} target="_blank" rel="noreferrer">{s.label}</a>)}
    </p>
  )
}

function Reading({ p }: { p: Person }) {
  const [a, , b] = p.dist, [la, lm, lb] = p.level
  const stated = p.p && (p.p[0] === p.p[1] ? percent(p.p[0]) : `${percent(p.p[0])}–${percent(p.p[1])}`)
  const peer = d.rungs[Math.round(expected(p))].toLowerCase()
  return (
    <p className="calc">
      Reading: about {percent(chance(p))} that today’s LLMs are conscious ({percent(a)} to {percent(b)});
      {LEVEL_DEFAULT(p.level) ? <> they say nothing about how conscious, so it is taken as equally likely anywhere from
        silkworm to human ({percent(ifConscious(p))} of a human on average, counting each animal as sentient).</>
        : <> if they are, {levelText([la, lm, lb])}{lm !== null && <>, most likely {levelText([lm, lm, lm])}</>}.</>}
      {" "}Priced in Rethink Priorities’ welfare ranges, that gives an LLM an expected welfare range of about{" "}
      {percent(worth(p))} of a human’s, {belowLadder(p) ? "below even a silkworm, so no animal on the ladder is an even trade"
        : <>level with {/^[aeiou]/.test(peer) ? "an" : "a"} {peer}</>}.
      {stated ? <> They stated {stated}{p.pTarget && ` ${p.pTarget}`}; the rest is the compiler’s reading.</>
        : <> They gave no number; this is the compiler’s reading of their words.</>}
    </p>
  )
}

// The chance, on the person's words, that an LLM isn't conscious at all: a point mass at the rock, drawn over the
// curve's rock end in its own darker grey. The curve near the rock can mean "almost surely not conscious" or
// "conscious, but faintly"; this tells them apart.
function RockBar({ p }: { p: Person }) {
  const rock = 1 - chance(p)
  return (
    <span className="rockbar" title={`${percent(rock)} chance an LLM is not conscious at all`}>
      <i style={{ height: `${rock * 100}%` }} />
    </span>
  )
}

function Row({ p }: { p: Person }) {
  const [open, setOpen] = useState(false)
  // the name and the reading take the ladder colour at where the curve's mass sits on average
  const ink = legible(colorAt(expected(p)))
  const mark = markOf(p)
  return (
    <li className={open ? "row expanded" : "row"}>
      <button className="head" onClick={() => setOpen(!open)} aria-expanded={open}>
        <span className="who" title={`${p.name}, ${p.who}${mark ? ` · ${mark.label}${p.viewInferred ? " (inferred)" : ""}` : ""}`}>
          <b style={{ color: ink }}>
            {/* an AI row has no theory of its own, so its badge takes the mark's place */}
            {p.ai ? <i className="ai-badge">AI</i> : <Glyph shape={mark?.shape} family={mark?.family} hollow={p.viewInferred} />}{p.name}
          </b><small>{p.who}</small>
        </span>
        <Track>
          {!belowLadder(p) && <><Curve p={p} /><i className="mark" style={{ left: `${pct(expected(p))}%` }} /></>}
          <RockBar p={p} />
        </Track>
        <span className="place" style={{ color: ink }}>{placeText(p)}</span>
      </button>
      {open && (
        <div className="detail">
          {p.quote && <blockquote>{p.quote}</blockquote>}
          {p.note && <p>{p.note}</p>}
          <Reading p={p} />
          <p className="chips">
            {p.basis.map(b => <span key={b} className="chip">{b}</span>)}
            {p.view !== "n/a" && <span className="chip">View: {p.view}</span>}
          </p>
          <Sources src={p.src} />
        </div>
      )}
    </li>
  )
}

// ── tabs ──────────────────────────────────────────────────────────────────

const X_LINK = <a href="https://x.com/typebulbit" target="_blank" rel="noreferrer">@typebulbit</a>

function LadderTab() {
  const [hover, setHover] = useState<number | null>(null)   // the rung whose distribution is showing
  const shown = [...d.people].sort((x, y) => expected(y) - expected(x) || chance(y) - chance(x))   // most conscious first
  return <>
    <InkDefs />
    <div className="panel">
      <p className="how">
        Forced to torture either an LLM or an animal, which animal is the even trade? Each curve is what one person’s
        words imply, priced in Rethink Priorities’ welfare ranges. The gray bar is the chance, on their reading, that an
        LLM isn’t conscious at all.
      </p>

      <div className="axis">
        <span />
        <span className="track labels">
          {d.rungs.map((r, i) => (
            <em key={r} tabIndex={0} style={{ left: `${pct(i)}%` }}
              onMouseEnter={() => setHover(i)} onMouseLeave={() => setHover(null)}
              onFocus={() => setHover(i)} onBlur={() => setHover(null)}>
              <img src={icon(d.icons[i])} alt="" /><span>{r}</span>
            </em>
          ))}
        </span>
        <span /><span />
        <ScaleBar hover={hover} />
        <span />
      </div>

      <ul className="rows">
        {shown.map(p => <Row key={p.name} p={p} />)}
      </ul>
      <ViewKey />
    </div>
    <p className="foot ping">Any of these attributions seem wrong? Ping me on X at {X_LINK} and I’ll fix it.</p>
  </>
}

function RpTable() {
  const HUMAN_NEURONS = 86e9
  const MAX_POW = 11   // 10^11 is past a human's 86 billion, so the bar's full length
  // a neuron count in scientific notation (8.6 × 10^10), with a bar whose length is its power of ten (a log scale);
  // the full count on hover
  const neurons = (share: number) => {
    const n = share * HUMAN_NEURONS
    if (n === 0) return <td className="count">0</td>
    const pow = Math.log10(n), exp = Math.floor(pow)
    return (
      <td className="count" title={`about ${(+n.toPrecision(3)).toLocaleString("en")} neurons`}>
        {+(n / 10 ** exp).toFixed(1)} × 10<sup>{exp}</sup>
        <span className="logbar"><i style={{ width: `${(pow / MAX_POW) * 100}%` }} /></span>
      </td>
    )
  }
  return (
    <table className="anchors">
      <thead><tr><th>Rung</th><th>Chance sentient</th><th>Range if sentient</th><th>Ladder value</th><th>Neurons</th></tr></thead>
      <tbody>
        {d.rungs.map((r, i) => [r, i] as const).reverse().map(([r, i]) => {   // Human first, as on the Ladder tab
          const p = d.rp[i]
          const v = rungVal[i]
          return (
            <tr key={r}>
              <td>{r}</td>
              {/* plain, not ladder-coloured: only the ladder value is a position on the ladder */}
              <td className="num plain">{p.psent === undefined ? "–" : percent(p.psent)}</td>
              <td className="num plain">{p.ifSentient ?? "–"}</td>
              <td className="num" style={{ color: legible(colorAt(i)) }}>{+v.toPrecision(2)}</td>
              {neurons(p.neurons)}
            </tr>
          )
        })}
      </tbody>
    </table>
  )
}

function AboutTab() {
  return (
    <div className="about">
      <p className="lede">
        Forced to torture either an LLM or an animal, which animal is the even trade? This page works out what each
        prominent person’s words imply. On expected value, an LLM counts for the chance it’s conscious times how much it
        would feel if it were, and each curve places that on the ladder of animals. Few of them would make the trade
        themselves: it is their words run through one calculation, not their answer.
      </p>
      <p>
        Each reading has two parts: how likely the person thinks it is that LLMs are conscious at all, and, if they are,
        how conscious. Few people give a number, and fewer say how conscious; where they don’t, a conscious LLM is taken as
        equally likely anywhere from silkworm to human, about a third of a human’s welfare range. That default sets how
        conscious for 30 of the 33 rows, so for most people the placement comes down to the chance alone. Most readings
        are the compiler’s; where someone stated a number, it anchors theirs, and each row says which. Where someone gave
        no number, their words set the reading (lowest, most likely, highest chance): a flat no (“they are not”) 0, 0.2%,
        2%; a hedged no (“vanishingly unlikely”, “very skeptical”) 0, 0.5%, 5%; a no held as a belief (“I don’t think
        they are”, “inclined to think not”) 1%, 4%, 15%; “we don’t know” anywhere from 1% to 30%. Where a reading is a
        range with no most likely value, every order of magnitude in it counts the same, so “between 1% and 70%” comes
        out near 14%, not at its 35% midpoint.
      </p>
      <p>
        On the Ladder tab, each curve’s tick is the best estimate, and its spread is the spread of the chance in the
        reading, with how conscious averaged. Each curve is scaled to its own peak, so heights compare shapes, not
        amounts. The gray bar is absolute: the reading’s chance that an LLM isn’t conscious at all, full height for
        certain. Where the best estimate falls below the silkworm, the simplest animal on the ladder, no animal is an
        even trade, and the row shows only its gray bar.
      </p>
      <p>
        Caveats: some people speak of consciousness, others of sentience or moral patienthood, and the page treats them as
        one. Torture needs suffering, not just consciousness, and a chance of being conscious is at least the chance of
        being able to suffer, so for this trade the readings lean high. The trade is what each person’s words imply on
        expected value, not what they would answer; some would refuse the calculation. Readings rest only on what was said
        in 2026. The people are prominent voices who said something on the record this year, not a survey of experts:
        several rows come from the same few podcasts, and some well-known names are missing only because they said
        nothing about it in 2026. Rows marked AI are models’ views of themselves, from Anthropic’s publications, and
        training shapes what models say about this.
      </p>

      <h2>The animals</h2>
      <p>
        The animals come from Rethink Priorities’ 2023 Moral Weight Project, from the 10,000 simulation samples in their{" "}
        <a href="https://github.com/rethinkpriorities/public_moral_weight_and_sentience" target="_blank"
        rel="noreferrer">published code and data</a>. Hover an animal on the ladder to see its spread. The spreads are
        wide: octopus and shrimp could sit far higher than their medians. The fly is RP’s black soldier fly and the fish
        its carp; Rock and Human are 0 and 1 by definition. Neuron counts don’t follow the ladder, and are only one of the
        nine models RP blends.
      </p>
      <p>
        Each animal is placed the same way as an LLM: its chance of being sentient (RP’s mean) times its welfare range if
        it is sentient (RP’s median). So an LLM reading of 47% at bee level lands exactly on the bee, and when a reading
        says a conscious LLM would feel like a shrimp, it is priced in the shrimp’s range if sentient, without the
        shrimp’s own doubt counted on top. On this footing the fish and the bee nearly tie, the bee just ahead. RP’s
        headline medians instead multiply the two inside each sample and come out lower (the shrimp at 0.031, not
        0.068); set against these LLM readings, they would place every LLM about a rung too high.
      </p>
      <p>
        The range if sentient is a median, not a mean. RP’s spreads are lopsided, with long tails upward: the means run
        two to three times the medians for the silkworm, fly and shrimp, and would put the shrimp above the bee and the
        fish, and the octopus above the chicken.
      </p>
      <RpTable />

      <p className="foot">
        Compiled 7–8 October 2026, with research help from Claude Opus 5.5, which also appears in the table; its row uses
        only Anthropic’s published system card.
      </p>
      <p className="foot">
        Credit for visualisation: I ported the code a while ago but since forgot the author - if it’s you please contact
        me on X at {X_LINK}. I would love to credit you.
      </p>
      <p className="foot">
        Creature icons:{" "}
        <a href="https://github.com/jdecked/twemoji" target="_blank" rel="noreferrer">Twemoji</a>, licensed under{" "}
        <a href="https://creativecommons.org/licenses/by/4.0/" target="_blank" rel="noreferrer">CC-BY 4.0</a>.
      </p>
    </div>
  )
}

function App() {
  const [tab, setTab] = useState<"ladder" | "about">("ladder")
  const tabs = [["ladder", "Ladder"], ["about", "About"]] as const
  return (
    <div className="wrap">
      <h1>AI vs. Shrimp</h1>
      <div className="tabs" role="tablist">
        {tabs.map(([id, label]) => (
          <button key={id} role="tab" aria-selected={tab === id} className={tab === id ? "tab on" : "tab"}
            onClick={() => setTab(id)}>{label}</button>
        ))}
      </div>
      {tab === "ladder" ? <LadderTab /> : <AboutTab />}
    </div>
  )
}

// ── backdrop ──────────────────────────────────────────────────────────────

// A 3D neuron (three.js, bloom) as the backdrop: every 4-10 s a pulse runs up its input axon and the cell fires,
// an action potential spreading through the dendrites. Rendered glow-on-black; styles.css blends it into the page.
function NeuralBg() {
  const ref = useRef<HTMLCanvasElement>(null)
  useEffect(() => {
    const canvas = ref.current!
    const still = matchMedia("(prefers-reduced-motion: reduce)").matches
    const INPUT_LENGTH = 45, SOMA = 3.3, CAM_R = 58   // further back than the original 45: the whole cell, with room around it
    const rand = Math.random

    const renderer = new THREE.WebGLRenderer({ canvas, antialias: false, powerPreference: "low-power" })
    renderer.setPixelRatio(Math.min(devicePixelRatio || 1, 1.5))
    renderer.setSize(innerWidth, innerHeight, false)
    renderer.setClearColor(0x000000, 1)
    const scene = new THREE.Scene()
    scene.fog = new THREE.FogExp2(0x000000, 0.022)
    const camera = new THREE.PerspectiveCamera(52, innerWidth / innerHeight, 0.1, 1000)
    camera.position.set(0, 8, CAM_R)
    camera.lookAt(0, 0, 0)

    const material = new THREE.ShaderMaterial({
      vertexShader: `
        attribute float aIsInput;
        varying vec3 vWorldPos;
        varying vec3 vNormal;
        varying float vIsInput;
        varying float vDist;
        void main() {
          vIsInput = aIsInput;
          vec4 worldPos = modelMatrix * vec4(position, 1.0);
          vWorldPos = worldPos.xyz;
          vDist = length(worldPos.xyz);
          vNormal = normalize(normalMatrix * normal);
          gl_Position = projectionMatrix * viewMatrix * worldPos;
        }
      `,
      fragmentShader: `
        uniform float uTime;
        uniform float uPulseProgress;
        uniform float uActivation;
        uniform float uFlash;
        uniform vec3 uCameraPos;
        varying vec3 vWorldPos;
        varying vec3 vNormal;
        varying float vIsInput;
        varying float vDist;

        float hash(vec3 p) {
          p = fract(p * 0.3183099 + .1);
          p *= 17.0;
          return fract(p.x * p.y * p.z * (p.x + p.y + p.z));
        }
        float noise(vec3 x) {
          vec3 i = floor(x);
          vec3 f = fract(x);
          f = f*f*(3.0-2.0*f);
          return mix(
            mix(mix(hash(i+vec3(0,0,0)),hash(i+vec3(1,0,0)),f.x),
                mix(hash(i+vec3(0,1,0)),hash(i+vec3(1,1,0)),f.x),f.y),
            mix(mix(hash(i+vec3(0,0,1)),hash(i+vec3(1,0,1)),f.x),
                mix(hash(i+vec3(0,1,1)),hash(i+vec3(1,1,1)),f.x),f.y),f.z);
        }
        vec3 palette(float t, vec3 a, vec3 b, vec3 c, vec3 d) {
          return a + b * cos(6.28318*(c*t+d));
        }

        void main() {
          vec3 viewDir = normalize(uCameraPos - vWorldPos);
          float fresnel = pow(1.0 - max(dot(vNormal, viewDir), 0.0), 3.0);
          float n1 = noise(vWorldPos * 0.5 + uTime * 0.2);
          float n2 = noise(vWorldPos * 2.0 - uTime * 0.5);
          vec3 baseColor = vec3(0.01, 0.018, 0.03) + (vec3(0.08, 0.22, 0.28) * fresnel * n1);
          baseColor *= (0.5 + 0.5 * n2);

          vec3 pulseColor = vec3(0.0);
          if (vIsInput > 0.5 && uPulseProgress > -5.0) {
            float pDist = abs(vDist - uPulseProgress);
            float core = exp(-pDist * pDist * 3.0);
            float trail = smoothstep(6.0, 0.0, vDist - uPulseProgress) * smoothstep(-2.0, 0.0, uPulseProgress - vDist);
            float pi = max(core * 3.0, trail * 1.5);
            pulseColor = vec3(3.5, 1.0, 0.1) * pi * (0.8 + 0.2*n2);
          }

          vec3 actColor = vec3(0.0);
          if (uActivation > 0.0) {
            float distFromWave = vDist - uActivation;
            float waveFront = exp(-pow(distFromWave, 2.0) * 0.2) * step(0.0, -distFromWave);
            float residual = smoothstep(uActivation, uActivation - 25.0, vDist);
            float actIntensity = waveFront * 4.0 + residual * 1.5;
            actIntensity *= (0.6 + 0.4 * noise(vWorldPos * 1.5 - uTime * 2.0));
            vec3 dir = normalize(vWorldPos);
            float angle = atan(dir.z, dir.x);
            vec3 rainbow = palette(
              angle * 0.15 + vDist * 0.05 - uTime * 0.5,
              vec3(0.5,0.5,0.5), vec3(0.5,0.5,0.5),
              vec3(1.0,1.0,1.0), vec3(0.00,0.33,0.67)
            );
            actColor = rainbow * actIntensity * 1.5;
            if (vDist < 4.0) {
              float somaFlash = exp(-pow(uActivation * 0.2, 2.0)) * uFlash;
              actColor += vec3(1.0, 0.9, 0.8) * somaFlash;
            }
          }

          gl_FragColor = vec4(baseColor + pulseColor + actColor, 1.0);
        }
      `,
      uniforms: {
        uTime: { value: 0 },
        uPulseProgress: { value: -10 },
        uActivation: { value: 0 },
        uFlash: { value: 1.6 },
        uCameraPos: { value: new THREE.Vector3() },
      },
    })

    // the neuron: a lumpy soma, one input axon from the left, 18 wandering dendrites with side branches
    const group = new THREE.Group()
    scene.add(group)
    const wander = (start: THREE.Vector3, dir: THREE.Vector3, length: number, segments: number, jitter: number, end?: THREE.Vector3) => {
      const pts = [start.clone()]
      let curr = start.clone()
      const d = dir.clone().normalize()
      for (let i = 0; i < segments; i++) {
        d.x += (rand() - 0.5) * jitter; d.y += (rand() - 0.5) * jitter; d.z += (rand() - 0.5) * jitter
        d.normalize()
        curr = curr.clone().add(d.clone().multiplyScalar(length / segments))
        pts.push(curr)
      }
      if (end) { pts[pts.length - 1] = end.clone().add(new THREE.Vector3(-1.5, 0, 0)); pts.push(end.clone()) }
      return new THREE.CatmullRomCurve3(pts)
    }
    const branch = (curve: THREE.CatmullRomCurve3, radius: number, isInput: boolean) => {
      const geo = new THREE.TubeGeometry(curve, Math.floor(curve.getLength() * 2.5), radius, 8, false)
      const pos = geo.attributes.position, norm = geo.attributes.normal, uv = geo.attributes.uv
      for (let i = 0; i < pos.count; i++) {   // taper toward the tip
        const t = isInput ? 1 : 1 - uv.getX(i)
        const shrink = radius * (1 - Math.pow(t, 0.6))
        pos.setXYZ(i, pos.getX(i) - norm.getX(i) * shrink, pos.getY(i) - norm.getY(i) * shrink, pos.getZ(i) - norm.getZ(i) * shrink)
      }
      geo.computeVertexNormals()
      geo.setAttribute("aIsInput", new THREE.BufferAttribute(new Float32Array(pos.count).fill(isInput ? 1 : 0), 1))
      group.add(new THREE.Mesh(geo, material))
      return curve
    }
    const somaGeo = new THREE.IcosahedronGeometry(SOMA, 16)
    const sp = somaGeo.attributes.position
    for (let i = 0; i < sp.count; i++) {
      const v = new THREE.Vector3().fromBufferAttribute(sp, i)
      const n = Math.sin(v.x * 2) * Math.cos(v.y * 2) * Math.sin(v.z * 2) * 0.5 + Math.sin(v.x * 5 + v.y * 3) * 0.2
      v.add(v.clone().normalize().multiplyScalar(n))
      sp.setXYZ(i, v.x, v.y, v.z)
    }
    somaGeo.computeVertexNormals()
    somaGeo.setAttribute("aIsInput", new THREE.BufferAttribute(new Float32Array(sp.count).fill(0), 1))
    group.add(new THREE.Mesh(somaGeo, material))
    branch(wander(new THREE.Vector3(-45, 0, 0), new THREE.Vector3(1, 0, 0), 46, 30, 0.05, new THREE.Vector3(-SOMA * 0.1, 0, 0)), 0.6, true)
    for (let i = 0; i < 18; i++) {
      let phi = rand() * Math.PI * 2
      const theta = Math.acos(rand() * 2 - 1)
      if (Math.cos(phi) * Math.sin(theta) < -0.3) phi = phi > Math.PI ? phi - Math.PI : phi + Math.PI
      const dir = new THREE.Vector3(Math.cos(phi) * Math.sin(theta), Math.sin(phi) * Math.sin(theta), Math.cos(theta))
      const length = 20 + rand() * 30, r = 0.4 + rand() * 0.3
      const main = branch(wander(dir.clone().multiplyScalar(SOMA * 0.8), dir, length, 25, 0.4), r, false)
      for (let j = 0, k = 2 + Math.floor(rand() * 4); j < k; j++) {
        const t = 0.2 + rand() * 0.6
        const tangent = main.getTangent(t)
        const rv = new THREE.Vector3(rand() - 0.5, rand() - 0.5, rand() - 0.5).normalize()
        const bDir = tangent.clone().cross(rv).normalize().add(tangent.multiplyScalar(0.5)).normalize()
        branch(wander(main.getPoint(t), bDir, (1 - t) * length * (0.4 + rand() * 0.4), 15, 0.6), r * (1 - t) * 0.8, false)
      }
    }
    const dust = (count: number, spread: number, color: number, size: number, opacity: number) => {
      const geo = new THREE.BufferGeometry()
      const p = new Float32Array(count * 3)
      for (let i = 0; i < p.length; i++) p[i] = (rand() - 0.5) * spread
      geo.setAttribute("position", new THREE.BufferAttribute(p, 3))
      const pts = new THREE.Points(geo, new THREE.PointsMaterial({
        color, size, transparent: true, opacity, blending: THREE.AdditiveBlending, depthWrite: false, sizeAttenuation: true,
      }))
      scene.add(pts)
      return pts
    }
    const dustA = dust(1200, 120, 0x224466, 0.08, 0.25)
    const dustB = dust(400, 90, 0x003355, 0.16, 0.18)
    const dustC = dust(120, 60, 0x00aacc, 0.3, 0.12)

    // bloom picks up only what exceeds 1.0: the travelling pulse and the action potential, never the idle cell
    const composer = new EffectComposer(renderer)
    const bloom = new UnrealBloomPass(new THREE.Vector2(innerWidth, innerHeight), 1.0, 0.8, 1.0)
    composer.addPass(new RenderPass(scene, camera))
    composer.addPass(bloom)

    // 0 idle, 1 pulse travelling up the axon, 2 action potential spreading out
    let state = 0, pulse = -10, act = 0, t = 0, frames = 0, firings = 0, raf = 0
    let nextFire = 2 + rand() * 3, last = performance.now(), theme = ""
    const fire = () => {
      state = 1; pulse = INPUT_LENGTH; act = 0; firings++
      material.uniforms.uActivation.value = 0
      nextFire = t + 4 + rand() * 6   // start to start; a firing still running defers the next until it ends
    }
    const step = (dt: number) => {
      t += dt
      const a = t * (Math.PI * 2 / 110)   // one slow orbit every ~2 minutes, with a gentle bob
      camera.position.set(Math.sin(a) * CAM_R, 8 + Math.sin(t * 0.17) * 2.5, Math.cos(a) * CAM_R)
      camera.lookAt(0, 0, 0)
      dustA.rotation.y += dt * 0.008; dustA.rotation.x += dt * 0.003
      dustB.rotation.y -= dt * 0.005; dustB.rotation.z += dt * 0.002
      dustC.rotation.y += dt * 0.015
      material.uniforms.uTime.value = t
      if (state === 0 && t >= nextFire) fire()
      if (state === 1) {
        pulse -= dt * 35
        material.uniforms.uPulseProgress.value = pulse
        if (pulse <= 2) { state = 2; pulse = -10; material.uniforms.uPulseProgress.value = -10; act = 0 }
      } else if (state === 2) {
        act += dt * 20
        material.uniforms.uActivation.value = act
        if (act > 75) { state = 0; material.uniforms.uActivation.value = 0 }
      }
    }
    const render = () => {
      material.uniforms.uCameraPos.value.copy(camera.position)
      composer.render()
      frames++
    }
    const loop = () => {
      raf = requestAnimationFrame(loop)
      const now = performance.now()
      if (now - last < 15) return   // at most ~60 fps, even on a 120 Hz display
      step(Math.min((now - last) / 1000, 0.1))
      last = now
      render()
    }
    const start = () => {
      cancelAnimationFrame(raf); raf = 0
      if (still) render()
      else if (!document.hidden) { last = performance.now(); loop() }
    }

    // theme: the canvas is always glow-on-black; CSS screens it onto the dark page and inverts and multiplies it onto
    // the light one, where the glow turns to ink, so the light theme gets a softer bloom and soma flash
    const applyTheme = () => {
      theme = document.documentElement.getAttribute("data-theme") === "dark" ? "dark" : "light"
      bloom.strength = theme === "dark" ? 1.0 : 0.7
      material.uniforms.uFlash.value = theme === "dark" ? 1.6 : 0.8
      if (still) render()
    }
    const themeObs = new MutationObserver(applyTheme)
    themeObs.observe(document.documentElement, { attributes: true, attributeFilter: ["data-theme"] })
    const onResize = () => {
      camera.aspect = innerWidth / innerHeight
      camera.updateProjectionMatrix()
      renderer.setSize(innerWidth, innerHeight, false)
      composer.setSize(innerWidth, innerHeight)
      if (still) render()
    }
    addEventListener("resize", onResize)
    document.addEventListener("visibilitychange", start)
    applyTheme()
    start()

    const off = tb.onMessage(m => {
      if (m === "bgtest") return {
        w: canvas.width, h: canvas.height, dpr: renderer.getPixelRatio(), seconds: +t.toFixed(1), frames, firings,
        state: ["idle", "pulse", "action potential"][state], nextFireIn: +(nextFire - t).toFixed(1),
        theme, still, hidden: document.hidden,
      }
      return undefined
    })
    return () => {
      cancelAnimationFrame(raf)
      removeEventListener("resize", onResize)
      document.removeEventListener("visibilitychange", start)
      themeObs.disconnect()
      off?.()
      scene.traverse(o => {
        if (o instanceof THREE.Mesh || o instanceof THREE.Points) { o.geometry.dispose(); (o.material as THREE.Material).dispose() }
      })
      for (const p of composer.passes) p.dispose()
      composer.dispose()
      renderer.dispose()
    }
  }, [])
  return <canvas ref={ref} className="neural" aria-hidden="true" />
}

createRoot(document.getElementById("root")!).render(<><NeuralBg /><App /></>)

// probe: `typebulb send <file> layout --wait` gives the axis track's and the first row's track and rock bar x-extents,
// which must line up
tb.onMessage(async m => {
  // `shape:<name>`: a row's first bins and where its tallest sits, to check how a curve meets the rock
  if (typeof m === "string" && m.startsWith("shape:")) {
    const p = d.people.find(p => p.name === m.slice(6))
    if (!p) return "no such row"
    const b = tradeShape(p).bins, top = Math.max(...b)
    return { first: b.slice(0, 14).map(v => +(v / top).toFixed(2)), peakRung: +((b.indexOf(top) + 0.5) * W).toFixed(2) }
  }
  if (m !== "layout") return undefined
  const x = (sel: string) => { const r = document.querySelector(sel)?.getBoundingClientRect(); return r && [Math.round(r.left), Math.round(r.right), Math.round(r.height)] }
  // hover a rung (React's mouseenter rides on mouseover), measure, then leave
  const hover = async (i: number) => {
    const em = document.querySelectorAll<HTMLElement>(".labels em")[i]
    em.dispatchEvent(new MouseEvent("mouseover", { bubbles: true, relatedTarget: document.body }))
    await new Promise(r => requestAnimationFrame(() => requestAnimationFrame(r)))
    return em
  }
  const leave = (em: HTMLElement) => em.dispatchEvent(new MouseEvent("mouseout", { bubbles: true, relatedTarget: document.body }))
  let em = await hover(0)
  const rockMarker = x(".scalebar > .sb-med"); leave(em)
  em = await hover(max)
  const humanMarker = x(".scalebar > .sb-med"); leave(em)
  // with the silkworm's spread raised, what's on top at the middle of its label text
  em = await hover(1)
  const t = em.querySelector("span")!.getBoundingClientRect()
  // the spread ignores the pointer, so let hit-testing see it for the check
  const dist = document.querySelector<SVGElement>(".scalebar > .dist")!
  dist.style.pointerEvents = "auto"; dist.querySelectorAll("path").forEach(p => (p.style.pointerEvents = "all"))
  const top = document.elementFromPoint(t.left + t.width / 2, t.top + t.height / 2)
  dist.style.pointerEvents = ""; dist.querySelectorAll("path").forEach(p => (p.style.pointerEvents = ""))
  const labelOnTop = !!top && em.contains(top); leave(em)
  return { axis: x(".axis .labels"), bar: x(".axis .scalebar"), row: x(".head .track"), rock: x(".head .rockbar"),
    rockMarker, humanMarker, labelOnTop, width: innerWidth }
})
```
**styles.css**

```css
/* ── tokens ─────────────────────────────────────────────────────────────── */
:root {
  /* the ladder's colour scale: grey toward Rock, blue mid-way, red toward Human */
  --cold: #9ca3af; --mid: #3b82f6; --hot: #dc0000;
  --fg: #1c1917; --muted: #57534e; --line: #e7e5e4; --bg: #fafaf9; --hover: #f5f5f4;
  --accent: #15803d; --violet: #7c3aed;   /* accent: green, well clear of the grey→blue→red scale */
  /* theory-of-consciousness marks: hues clear of the ladder's grey, blue and red and the backdrop's violet */
  --v-func: #0d9488; --v-bio: #db2777; --v-hw: #65a30d; --v-agn: #d97706;
  /* translucent panels: the backdrop shows through but never fights the text */
  --panel: color-mix(in srgb, var(--bg) 76%, transparent);
  --radius: 8px;
  --fs-xs: 11px; --fs-sm: 12px; --fs-base: 14px; --fs-md: 16px; --fs-lg: 18px;
}
html[data-theme="dark"] {
  --cold: #a8a29e; --mid: #60a5fa; --hot: #ff2d2d;
  --fg: #e7e5e4; --muted: #a8a29e; --line: #3a3532; --bg: #14110f; --hover: #2c2826;
  --accent: #4ade80; --violet: #a78bfa;
  --v-func: #2dd4bf; --v-bio: #f472b6; --v-hw: #bef264; --v-agn: #fbbf24;
  --panel: color-mix(in srgb, var(--bg) 90%, transparent);   /* the glow reads louder on dark */
}

/* ── page ───────────────────────────────────────────────────────────────── */
body {
  color: var(--fg);
  background:
    radial-gradient(1100px 600px at 90% -10%, color-mix(in srgb, var(--violet) 16%, transparent), transparent 65%),
    radial-gradient(900px 600px at -10% 110%, color-mix(in srgb, var(--accent) 14%, transparent), transparent 65%),
    var(--bg);
  background-attachment: fixed;
}
/* the neuron backdrop renders glow on black: light theme inverts it to ink and multiplies it in, so white drops out;
   dark theme screens it in, so black drops out. Either way the page's own background stays, and no slab shows. */
.neural {
  position: fixed; inset: 0; width: 100%; height: 100%; display: block; z-index: 0; pointer-events: none;
  filter: invert(1) hue-rotate(180deg); mix-blend-mode: multiply; opacity: 0.42;
}
html[data-theme="dark"] .neural { filter: none; mix-blend-mode: screen; opacity: 0.5; }
.wrap {
  position: relative; z-index: 1;
  max-width: 980px; margin: 0 auto; padding: 24px 16px 40px; font: var(--fs-base)/1.5 system-ui, sans-serif;
}
a { color: var(--accent); }
small { color: var(--muted); }
h1 { font-size: 32px; margin: 0 0 8px; text-align: center; }
h2 { font-size: 21px; margin: 32px 0 8px; }

.tabs { display: flex; justify-content: center; gap: 4px; margin: 4px 0 12px; border-bottom: 1px solid var(--line); }
.tab {
  font: inherit; font-size: var(--fs-md); padding: 6px 16px; margin-bottom: -1px;
  border: 0; border-bottom: 2px solid transparent; background: none; color: var(--muted); cursor: pointer;
}
.tab.on { color: var(--fg); border-bottom-color: var(--accent); font-weight: 600; }

/* No backdrop-filter on panels: it would make the sticky axis re-blur the panel's own tint and double it. */
.panel, .about { background: var(--panel); border-radius: var(--radius); }
.foot { font-size: var(--fs-base); margin-top: 16px; color: var(--muted); }

/* ── ladder tab ─────────────────────────────────────────────────────────── */
.panel { padding: 12px 8px 4px; }
.how, .ping { text-align: center; font-size: var(--fs-md); }
.how { color: var(--fg); }

/* name | track | placement: the axis and every row share these columns, so their tracks line up */
/* name | rock bar | track | placement */
.axis, .head { display: grid; grid-template-columns: 210px 1fr 190px; gap: 12px; align-items: center; }
.track { position: relative; height: 14px; margin: 0 10px; }
.track > i { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--line); }   /* rung ticks */

/* the axis sticks while the rows scroll under it, so it is opaque and spans the panel's padding: nothing shows through */
.axis {
  position: sticky; top: 0; z-index: 2; margin: 0 -8px; padding: 6px 8px 2px;
  background: var(--bg); border-bottom: 1px solid var(--line);
}
.labels { height: 46px; }
.labels em {
  position: absolute; bottom: 4px; z-index: 2; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  font-style: normal; font-size: var(--fs-xs); color: var(--muted); white-space: nowrap; cursor: default; outline: none;
}
.labels img { width: 20px; height: 20px; }
/* the hovered animal's spread rises behind the labels; a halo in the page colour keeps the names reading on top */
.labels em span { text-shadow: 0 0 2px var(--bg), 0 0 3px var(--bg), 0 0 4px var(--bg); }
.labels em:hover, .labels em:focus { color: var(--fg); }

/* the colour bar under the animals; hovering an animal morphs its top edge into that animal's distribution,
   drawn 52px tall from the bar's bottom so it rises into the space behind the animals (which stay on top) */
.scalebar { height: 8px; margin: 4px 10px 8px; }
.scalebar > .dist { position: absolute; left: 0; bottom: 0; width: 100%; height: 52px; z-index: 1; pointer-events: none; }
.dist path { transition: d 0.35s ease, opacity 0.35s ease; }
.dist .edge { opacity: 0; }
.dist .edge.on { opacity: 1; }
/* scoped under .scalebar so the rung-tick rule (.track > i) can't override these */
.scalebar > .sb-med {
  top: -7px; bottom: -7px; width: 4px; margin-left: -2px; border-radius: 2px;
  background: var(--fg); box-shadow: 0 0 0 1.5px var(--bg);
}
.scalebar > .sb-cap {   /* the 95th percentile runs past Human */
  top: -5px; bottom: -5px; width: 2px; margin-left: -1px;
  background: repeating-linear-gradient(var(--fg) 0 2px, transparent 2px 4px);
}

.rows { list-style: none; margin: 0; padding: 0; }
.row { border-bottom: 1px solid var(--line); }
.head {
  width: 100%; padding: 3px 0; border: 0; background: none; color: inherit; font: inherit; line-height: 1.3;
  text-align: left; cursor: pointer;
}
.head:hover, .expanded .head { background: color-mix(in srgb, var(--hover) 75%, transparent); }
/* AI models' views of themselves: a badge in the functionalism colour sets them apart from the people */
.ai-badge {
  display: inline-block; margin-right: 6px; padding: 0 5px; border-radius: 4px; vertical-align: 1px;
  background: var(--v-func); color: var(--bg); font-size: var(--fs-xs); font-style: normal; font-weight: 700; letter-spacing: 0.04em;
  -webkit-text-fill-color: var(--bg);
}
.who { display: flex; flex-direction: column; padding-left: 6px; }
.who small { font-size: var(--fs-sm); }
/* the theory-of-consciousness mark before each name, and the key under the rows */
.vm {
  display: inline-block; flex: none; width: 9px; height: 9px; margin-right: 7px; vertical-align: 0;
  fill: var(--vm, var(--muted)); stroke: var(--vm, var(--muted)); stroke-width: 1.2;
}
.vm.func { --vm: var(--v-func); }
.vm.bio { --vm: var(--v-bio); }
.vm.phys { --vm: var(--v-hw); }
.vm.agn { --vm: var(--v-agn); }
.vm.hollow { fill: none; }
.view-key {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 20px; margin: 10px 0 6px;
  font-size: var(--fs-sm); color: var(--muted);
}
.view-key .vm { margin-right: 6px; }
.place { font-size: 13px; padding-right: 6px; }

/* a row's reading, drawn like the colour bar's distributions: the ladder's colours under a dark edge */
.head .track { height: 26px; }
/* the rock bar: centred on the rock, over the curve, in a grey darker than the curve's own so the two stay apart;
   it fills from the bottom, and the unfilled part is left clear */
.rockbar {
  position: absolute; top: 0; bottom: 0; left: 0; width: 6px; margin-left: -3px; overflow: hidden; border-radius: 2px;
}
.rockbar > i { position: absolute; left: 0; right: 0; bottom: 0; background: color-mix(in oklab, var(--cold) 50%, var(--fg)); }
.curve { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.curve .fill { fill: url(#ladder-fill); }
.curve .edge { fill: none; stroke: var(--fg); stroke-width: 1.5; }
.head .track > .mark { width: 2px; margin-left: -1px; background: var(--fg); }   /* the even trade's best estimate */

.detail { padding: 4px 6px 14px; }
.detail p { margin: 6px 0; }
blockquote { margin: 6px 0; padding: 4px 0 4px 12px; border-left: 3px solid var(--accent); font-style: italic; }
.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip { font-size: var(--fs-xs); padding: 1px 8px; border: 1px solid var(--line); border-radius: 10px; color: var(--muted); }
.sources { display: flex; flex-wrap: wrap; gap: 4px 14px; font-size: var(--fs-sm); }

/* ── about tab: prose on one narrower panel ─────────────────────────────── */
.about { max-width: 760px; margin: 0 auto; padding: 20px 28px 24px; }
.about > :first-child { margin-top: 0; }
.about p { font-size: var(--fs-md); }
.about .lede { font-size: var(--fs-lg); margin: 0 0 6px; }
.about .foot { font-size: var(--fs-base); }

.anchors { border-collapse: collapse; font-size: var(--fs-md); margin: 8px auto 0; }
.anchors th, .anchors td { text-align: left; padding: 6px 18px; border-bottom: 1px solid var(--line); }
.anchors tr:last-child td { border-bottom: 0; }
.anchors th { color: var(--muted); font-weight: 500; }
.anchors .num { font-weight: 600; font-variant-numeric: tabular-nums; }
.anchors .count { white-space: nowrap; font-variant-numeric: tabular-nums; color: var(--muted); }
/* neutral grey, not the ladder's colours: neuron count is not a position on the sentience scale */
.logbar { display: inline-block; width: 70px; height: 6px; margin-left: 8px; vertical-align: middle; border-radius: 3px; background: var(--line); }
.logbar i { display: block; height: 100%; border-radius: 3px; background: color-mix(in srgb, var(--fg) 45%, transparent); }

/* ── responsive ─────────────────────────────────────────────────────────── */
/* wide: name, role and placement on one line each, truncated with the full text on hover */
@media (min-width: 820px) {
  .wrap { max-width: 1240px; }
  .axis, .head { grid-template-columns: clamp(220px, 26vw, 330px) 1fr clamp(160px, 20vw, 260px); }
  .who { flex-direction: row; align-items: baseline; gap: 8px; white-space: nowrap; overflow: hidden; }
  .who b { flex: none; }
  .who small { margin-left: auto; text-align: right; }   /* the role sits flush right in the name column */
  .who small, .place { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}
/* narrow: each row's track drops below its name; the axis shows icons only */
@media (max-width: 680px) {
  .head { grid-template-columns: 1fr auto; gap: 4px 8px; }
  .head .track { grid-column: 1 / -1; grid-row: 2; }
  .place { text-align: right; }
  .axis { grid-template-columns: 1fr; }
  .axis > span:not(.track) { display: none; }
  .labels { height: 28px; }
  .labels em span { display: none; }
}
```
**index.html**

```html
<div id="root"></div>
```
**data.txt**

```txt
{
  "rungs": [
    "Rock",
    "Silkworm",
    "Fly",
    "Shrimp",
    "Fish",
    "Bee",
    "Octopus",
    "Chicken",
    "Pig",
    "Human"
  ],
  "icons": [
    "1faa8",
    "1f41b",
    "1fab0",
    "1f990",
    "1f41f",
    "1f41d",
    "1f419",
    "1f414",
    "1f416",
    "1f9cd"
  ],
  "people": [
    {
      "name": "Mustafa Suleyman",
      "who": "CEO, Microsoft AI",
      "year": 2026,
      "basis": [
        "Flat no"
      ],
      "quote": "AIs do not have rights, feelings, or consciousness. And we must not train them to act as though they do.",
      "note": "Also argues that acknowledging uncertainty “should not mean giving equal weight to any and all claims”, and that consciousness is “very likely biological”, so emotion, pleasure and pain “can’t arise in LLMs”.",
      "src": [
        {
          "label": "A warning about model welfare (16 Sep 2026)",
          "url": "https://mustafa-suleyman.ai/a-warning-about-model-welfare"
        }
      ],
      "dist": [
        0,
        0.002,
        0.02
      ],
      "view": "biological",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Gary Marcus",
      "who": "Cognitive scientist, AI critic",
      "year": 2026,
      "basis": [
        "Hedged no"
      ],
      "quote": "There is no reason to think that Claude feels anything at all.",
      "note": "Replying to Dawkins: “Claude’s outputs are the product of a form of mimicry, rather than as a report of genuine internal states.” On 31 May 2026 he turned the same argument on a new Hinton interview: “Consciousness is about internal states; the mimicry, no matter how rich, proves very little.”",
      "src": [
        {
          "label": "Richard Dawkins and The Claude Delusion (2 May 2026)",
          "url": "https://garymarcus.substack.com/p/richard-dawkins-and-the-claude-delusion"
        },
        {
          "label": "The Pope appears to understand AI better than Geoffrey Hinton does (31 May 2026)",
          "url": "https://garymarcus.substack.com/p/the-pope-appears-to-understand-ai"
        }
      ],
      "dist": [
        0,
        0.005,
        0.05
      ],
      "view": "unclear",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Christof Koch",
      "who": "Neuroscientist, IIT proponent",
      "year": 2026,
      "basis": [
        "Flat no",
        "Framework (IIT)"
      ],
      "quote": "So an LLM according to IIT, will not feel, does not feel like anything.",
      "note": "Under IIT, today’s digital computers have “no intrinsic causal power or only a tiny, itsy bitsy amount of causal power, upon themselves”, so an LLM running on them feels nothing: “given the way computers, digital machines today run in the cloud, they are not conscious. They will never feel like anything.” He allows it in principle (“silicon is another piece of matter”) and on other hardware, and says “anything is possible but based on the… physical substrate I would say it’s not conscious.” The small tail rests on that “itsy bitsy” causal power; it isn’t used again to set how conscious a conscious LLM would be, which would count it twice.",
      "src": [
        {
          "label": "Beshara Magazine podcast interview (4 Sep 2026)",
          "url": "https://besharamagazine.org/?p=21228"
        },
        {
          "label": "Consciousness Experience interview (10 Sep 2026, ~52:43)",
          "url": "https://www.youtube.com/watch?v=jt2e8AX6e54"
        },
        {
          "label": "Eye on AI (30 Sep 2026, ~36:24)",
          "url": "https://www.youtube.com/watch?v=li1Ib1pOMcQ"
        }
      ],
      "dist": [
        0,
        0.002,
        0.02
      ],
      "view": "iit",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Susan Schneider",
      "who": "Philosopher, Florida Atlantic University",
      "year": 2026,
      "basis": [
        "Hedged no"
      ],
      "quote": "We don’t actually see evidence based on the utterances or text information we’re getting from these chatbots that they’re actually conscious.",
      "note": "“I’m very skeptical that chatbots are conscious”, and in July: “a large language model may very well not feel a thing, but I believe these other kinds of systems could be conscious.” She calls herself a panpsychist with a “quantum Darwinist theory of consciousness”, on which the hardware matters: of two AIs running the same algorithm, “it very well could be that only the former [neuromorphic] is conscious.” She still allows precautions “on the chance that they are conscious”. Her Economist essay could not be accessed.",
      "src": [
        {
          "label": "Is AI Conscious—or Just Convincing?, Templeton Foundation (7 May 2026)",
          "url": "https://www.templeton.org/?p=93126"
        },
        {
          "label": "Nautilus (16 Feb 2026)",
          "url": "https://nautil.us/chatgpt-gave-out-my-office-address-then-someone-showed-up-1267710"
        },
        {
          "label": "Machine Learning, The Sun (online 31 Jul 2026)",
          "url": "https://www.thesunmagazine.org/articles/608-machine-learning"
        },
        {
          "label": "Don’t mistake chatbot intelligence for consciousness, The Economist (20 Aug 2026, paywalled, unverified)",
          "url": "https://www.economist.com/by-invitation/2026/08/20/dont-mistake-chatbot-intelligence-for-consciousness"
        }
      ],
      "dist": [
        0,
        0.005,
        0.05
      ],
      "view": "panpsychist",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Anil Seth",
      "who": "Neuroscientist, biological naturalist",
      "year": 2026,
      "basis": [
        "Hedged no",
        "Framework (biological naturalism)"
      ],
      "quote": "My reading of the evidence means that my credence for AI consciousness is close to (but not exactly) zero.",
      "note": "At TED: “It might give the impression of being conscious, but it is vanishingly unlikely that it actually is”, and “conscious AI is off the table, at least for AI as we know it today.” In Noema he offers biological naturalism, “life (probably) matters”, while saying he has no “knock-down argument”; elsewhere he is “comfortable with functionalism broadly, but the question is: how far down do you have to go?”",
      "src": [
        {
          "label": "X (25 Sep 2026)",
          "url": "https://x.com/anilkseth/status/2103390204669079644"
        },
        {
          "label": "X (3 Oct 2026)",
          "url": "https://x.com/anilkseth/status/2106483026612162992"
        },
        {
          "label": "Why AI isn’t going to become conscious, TED2026 (published 1 May 2026)",
          "url": "https://www.ted.com/talks/anil_seth_why_ai_isn_t_going_to_become_conscious/transcript"
        },
        {
          "label": "The Mythology of Conscious AI, Noema (14 Jan 2026)",
          "url": "https://www.noemamag.com/the-mythology-of-conscious-ai/"
        }
      ],
      "dist": [
        0,
        0.005,
        0.05
      ],
      "view": "biological",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Jonathan Birch",
      "who": "Philosopher, LSE",
      "year": 2026,
      "basis": [
        "We don't know"
      ],
      "quote": "Your friend is not real. Your partner is not real. If there’s any consciousness in these systems at all, it’s a profoundly alien, un-human-like form of consciousness.",
      "note": "A self-described “AI consciousness centrist”: “we’re not in a position to rule out the idea that sentience might be about computations of the right kind”, and he rejects giving such ideas zero prior probability. He ranks the chatbot characters below “even very little ones like insects”, but that is about the persona, which he says is no more real than “Gandalf, Frodo Baggins”, not the system underneath, where “we don’t know what the candidates are”. His “flicker” hypothesis (brief flickers of consciousness per processing event) fixes no level: such a flicker “might feel like far longer from the system’s own point of view.”",
      "src": [
        {
          "label": "Earthling Ed, Is AI sentient? (10 Apr 2026, ~53:05–57:16)",
          "url": "https://www.youtube.com/watch?v=DLPFE91pXak"
        },
        {
          "label": "AI Consciousness: A Centrist Manifesto (versions of 16 Jan and 20 May 2026)",
          "url": "https://philpapers.org/archive/BIRACA-4.pdf"
        },
        {
          "label": "The Guardian (5 May 2026)",
          "url": "https://www.theguardian.com/technology/2026/may/05/richard-dawkins-ai-consciousness-anthropic-claude-openai-chatgpt"
        }
      ],
      "dist": [
        0.01,
        null,
        0.3
      ],
      "view": "agnostic",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Keith Frankish",
      "who": "Philosopher, illusionist, University of Sheffield",
      "year": 2026,
      "basis": [
        "Flat no",
        "Framework (illusionism)"
      ],
      "quote": "Absolutely not… its range of sensitivities to the world is about as impoverished as you can get.",
      "note": "Asked whether his view commits him to ChatGPT already being conscious. On illusionism, an LLM has one dimension of sensitivity: text in, text out. He adds that whether it is minimally conscious is “a terminological question… no bright lines anywhere”. Autonomous, self-modelling artificial agents might later earn the word.",
      "src": [
        {
          "label": "Alex O’Connor, Could Consciousness be an Illusion? (18 Jun 2026, ~2:00:00)",
          "url": "https://www.youtube.com/watch?v=557PDNSbcGE"
        },
        {
          "label": "Clip: Why AI Isn’t Conscious (10 Aug 2026)",
          "url": "https://www.youtube.com/watch?v=bFhw3FvJEe4"
        }
      ],
      "dist": [
        0,
        0.002,
        0.02
      ],
      "view": "illusionism",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Peter Godfrey-Smith",
      "who": "Philosopher of biology",
      "year": 2026,
      "basis": [
        "Hedged no"
      ],
      "quote": "You could ask, “Is their extraordinarily capable language use evidence of consciousness?” I would say, no.",
      "note": "Says the language comes “most likely from systems that don’t have even a little bit of consciousness”, and, assuming today’s systems are close to the transformer architecture with no hidden breakthrough, that “we can be confident that they’re not conscious”: “this is not a feeling subject.”",
      "src": [
        {
          "label": "Nautilus (21 Sep 2026)",
          "url": "https://nautil.us/could-ai-have-consciousness-that-isnt-human-like-1285156/"
        }
      ],
      "dist": [
        0,
        0.005,
        0.05
      ],
      "view": "biological",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Peter Singer",
      "who": "Ethicist",
      "year": 2026,
      "basis": [
        "No, held as a belief"
      ],
      "quote": "Leo states flatly that AI systems ‘do not undergo experiences.’ That may be true today, but it could cease to be true of future AI models. Even as a statement about current AI systems, Leo’s certainty is not warranted.",
      "note": "From his column on the Pope’s encyclical, which wants moral concern extended to “every sentient being, human and nonhuman, biological or possibly artificial.” On his podcast in April he reportedly said he considers Claude being conscious “a very low probability”; that quote could not be checked against the audio.",
      "src": [
        {
          "label": "The Pope’s AI vision and its limits, Project Syndicate (4 Jun 2026; Manila Times reprint)",
          "url": "https://www.manilatimes.net/2026/06/07/opinion/contributors/the-popes-ai-vision-and-its-limits/2360009"
        },
        {
          "label": "Lives Well Lived, Beyond Human (2 Apr 2026, ~40:50, unverified)",
          "url": "https://shows.acast.com/lives-well-lived/episodes/beyond-human-are-we-creating-ai-consciousness"
        }
      ],
      "dist": [
        0.01,
        0.04,
        0.15
      ],
      "view": "unclear",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Murray Shanahan",
      "who": "AI researcher, Google DeepMind; emeritus, Imperial College",
      "year": 2026,
      "basis": [
        "No, held as a belief"
      ],
      "quote": "For me, it’s not appropriate because the original home of the language of consciousness… is in our being together in the shared world with each other.",
      "note": "Answering whether words like “consciousness” and “feeling” suit a chatbot. He allows “a kind of awareness of its own thinking processes” that might apply “in a certain narrow sense to today’s large language models”, says “the question is still kind of open”, and resists “any kind of metaphysical understanding of the nature of consciousness”. A September paper he co-wrote gives illustrative LLM credences from below 0.01 to about 0.8; that is a sensitivity analysis, not his view.",
      "src": [
        {
          "label": "AI, Consciousness and Dharma Ethics, Oxford panel (11 Aug 2026, ~49:38–51:59)",
          "url": "https://www.youtube.com/watch?v=9BqsG_nPNsM"
        },
        {
          "label": "From cacophony to hierarchy, arXiv, co-authored (28 Sep 2026)",
          "url": "https://arxiv.org/abs/2609.35618"
        }
      ],
      "dist": [
        0.01,
        0.04,
        0.15
      ],
      "view": "other",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Steven Pinker",
      "who": "Cognitive psychologist",
      "year": 2026,
      "basis": [
        "Hedged no"
      ],
      "quote": "I think a better analogy might be the shrimp, or the insects, maybe even, you know, the bacteria… So when it comes to insects, same as with AIs.",
      "note": "“Intuitively I’m a total sceptic. I don’t for a moment think that there is an inner life there”, and he speaks of “the likelihood that there is no sentience going on in AI”. Yet “we can’t know that AIs are not conscious”. Puts shrimp “together with the mosquitoes”, and would give AI no weight against humans: “there’s no amount of human welfare that’s worth sacrificing for the welfare of an AI, like, zero.” The insect analogy is how he’d act under uncertainty, so it isn’t used as his level: his low chance spread over the animals lands near the insects anyway. He reasons in computational terms, “even if you were enough of a computational functionalist to say that certain styles of computation bring with them consciousness… even a computational functionalist would have to note that these are very, very different”, while crediting Seth’s substrate arguments: “what goes into both the computation and the physical substrate in humans, neither one of them is replicated in our AIs.”",
      "src": [
        {
          "label": "Conspicuous Cognition (7 Oct 2026)",
          "url": "https://www.conspicuouscognition.com/p/steven-pinker-on-ai-doom-and-consciousness"
        }
      ],
      "dist": [
        0,
        0.005,
        0.05
      ],
      "view": "functionalism",
      "viewInferred": true,
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Robert Long",
      "who": "Founder and executive director, Eleos AI",
      "year": 2026,
      "basis": [
        "No, held as a belief"
      ],
      "quote": "I actually do think that is some evidence against them currently being conscious. Not strong evidence I would take to the bank.",
      "note": "On how differently LLMs came about: “maybe that lessens the chance that they’re conscious.” No number in 2026. A computational functionalist who says such functionalists needn’t “think that computers are conscious”, and that “basically no one knows for sure if they’re conscious or not.” Says Eleos already tells some members of the public “we actually think it’s a bit less likely than you do that these systems are conscious.”",
      "src": [
        {
          "label": "Should We Care About AI Welfare?, Conspicuous Cognition (18 Apr 2026)",
          "url": "https://www.conspicuouscognition.com/p/should-we-care-about-ai-welfare-with"
        },
        {
          "label": "CIMC talk (22 Jul 2026, ~24:39)",
          "url": "https://www.youtube.com/watch?v=pZboVANDwNc"
        }
      ],
      "dist": [
        0.01,
        0.04,
        0.15
      ],
      "view": "functionalism",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Jeff Sebo",
      "who": "Philosopher, NYU",
      "year": 2026,
      "basis": [
        "No, held as a belief"
      ],
      "quote": "We may need to shift from preparing for the non-negligible possibility of welfare in future AI systems to responding to that possibility in current ones.",
      "note": "No 2026 number. He endorsed the Guardian’s paraphrase that current AI systems “are unlikely to be conscious”. In April: “Even if the probability that current AI systems are sentient is low, it will likely increase over time.” By September: “Until recently, we could reasonably treat the probability of welfare and moral significance in AI systems as negligible, even if nonzero… that position is becoming harder to sustain.”",
      "src": [
        {
          "label": "A Philosopher’s Guide to AI Welfare, AI Frontiers (17 Sep 2026)",
          "url": "https://ai-frontiers.org/articles/a-philosophers-guide-to-ai-welfare"
        },
        {
          "label": "The Guardian (5 May 2026), endorsed on X",
          "url": "https://x.com/jeffrsebo/status/2051788856400187893"
        },
        {
          "label": "Norton interview (17 Apr 2026)",
          "url": "https://nortonlearningblog.com/2026/04/who-matters-expanding-the-moral-circle-with-jeff-sebo/"
        }
      ],
      "dist": [
        0.01,
        0.04,
        0.15
      ],
      "view": "agnostic",
      "viewInferred": true,
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Henry Shevlin",
      "who": "Philosopher, Google DeepMind & Cambridge",
      "year": 2026,
      "basis": [
        "Probability"
      ],
      "quote": "Probably somewhere between 5% and 10% on any frontier AI system being conscious. […] I’m at least 70% for honeybees.",
      "note": "Asked for his credence on Claude Opus 4.7, he answered for “any frontier AI system”, adding that Chalmers’s 20% is “slightly higher than me”; in his next turn, replying to Dan Williams’s 20%: “Maybe I’m being overly cautious”, since he is “a consciousness liberal about the natural world”, which is where the honeybee figure comes from. Just before giving it he said he has “no clue” whether contemporary LLMs are conscious and is “genuinely super torn on the metaphysical-behaviorist push”. On X (5 May): current LLMs “probably lack consciousness, at least in the sense that we understand it in the case of humans or animals”, a view held “with fairly low confidence”. He gives no figure for how much a conscious LLM could feel; in the same conversation he argues that hedonic range grows with the complexity of a mind’s motivations, and that narrowing an AI’s preferences to make it a willing servant lowers its ceiling.",
      "src": [
        {
          "label": "Are We Building Conscious AI Servants?, Conspicuous Cognition (21 May 2026)",
          "url": "https://www.conspicuouscognition.com/p/richard-dawkins-claude-and-the-conscious"
        },
        {
          "label": "X (5 May 2026)",
          "url": "https://x.com/dioscuri/status/2051795905943318640"
        },
        {
          "label": "Should We Care About AI Welfare?, Conspicuous Cognition (18 Apr 2026)",
          "url": "https://www.conspicuouscognition.com/p/should-we-care-about-ai-welfare-with"
        }
      ],
      "p": [
        0.05,
        0.1
      ],
      "dist": [
        0.01,
        0.075,
        0.2
      ],
      "view": "agnostic",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "David Chalmers",
      "who": "Philosopher, NYU",
      "year": 2026,
      "basis": [
        "No, held as a belief"
      ],
      "quote": "I’m inclined to think the current language models are not conscious, but I think the case for future language models being conscious is not that easy to rebut.",
      "note": "No 2026 number: he recalls his 2023 article saying current models are “most likely not conscious”, and adds that “the view that they are conscious right now is very much a minority view.” He rejects biology as a requirement: “I don’t think it’s the stuff that matters. I think somehow it’s what it does.” In May: “even the most expert scientists and philosophers writing about this cannot be 100 per cent sure whether these models are conscious or not.”",
      "src": [
        {
          "label": "Berkeley Talks, When we talk to AI, what are we talking to? (talk 7 May 2026, transcript 10 Jul 2026)",
          "url": "https://news.berkeley.edu/2026/07/10/berkeley-talks-when-we-talk-to-ai-what-are-we-talking-to/"
        },
        {
          "label": "ABC News (30 May 2026)",
          "url": "https://www.abc.net.au/news/2026-05-30/artificial-intelligence-ai-will-it-be-conscious-in-the-future/106738770"
        }
      ],
      "dist": [
        0.01,
        0.04,
        0.15
      ],
      "view": "functionalism",
      "viewInferred": true,
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Dan Williams",
      "who": "Philosopher, Sussex",
      "year": 2026,
      "basis": [
        "Probability"
      ],
      "quote": "I’d say 20%. Seriously… but I am a computational functionalist, so I think it’s possible in principle.",
      "src": [
        {
          "label": "Are We Building Conscious AI Servants?, Conspicuous Cognition (21 May 2026)",
          "url": "https://www.conspicuouscognition.com/p/richard-dawkins-claude-and-the-conscious"
        }
      ],
      "p": [
        0.2,
        0.2
      ],
      "note": "His credence for Claude Opus 4.7. Says Anthropic’s emotion-concept findings are “not what’s driving my 20%”: it is uncertainty, functionalism, and that the systems are “so damn smart”.",
      "dist": [
        0.05,
        0.2,
        0.4
      ],
      "view": "functionalism",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Cameron Berg",
      "who": "AI consciousness researcher, founder of Reciprocal Research",
      "year": 2026,
      "basis": [
        "Probability"
      ],
      "quote": "It says twenty to forty percent… I’m in agreement with Opus four point seven. I think that is approximately the right probability band to be in given all the evidence that we have right now about these systems.",
      "note": "In April, on reading the 20–40% band in Claude Opus 4.7’s system card (for “morally relevant subjective experiences”), from an auto-transcript; just before, he recalls giving “something like twenty five to thirty five percent” four or five months earlier, in late 2025, and he says he sits in “coin flip territory” for deployed models, with different credences for training. In June he repeated 25–35% (Leaking Timeline show notes, not checked against the audio). In July, on Sam Harris’s podcast, he put LLMs at 20–40% against bees at 45–50% and humans near 90% for the computational properties that matter for consciousness, “the right ballpark” (scores on that scale, not credences), and said that once “the lights are on to some degree” there are “many degrees”. In Sept 2026 he co-wrote The Pain Axis: a linear pain direction found in 25 open-weight models; the paper says it has not shown the axis is consciously experienced.",
      "src": [
        {
          "label": "Leaking Timeline, show notes (1 Jun 2026, ~10:30; not checked against audio)",
          "url": "https://share.transistor.fm/s/0a758610"
        },
        {
          "label": "Cognitive Revolution podcast (23 Apr 2026, from 1:56:05)",
          "url": "https://www.cognitiverevolution.ai/does-learning-require-feeling-cameron-berg-on-the-latest-ai-consciousness-welfare-research/"
        },
        {
          "label": "Making Sense #487, Is AI Already Conscious? (31 Jul 2026, ~15:08)",
          "url": "https://podscripts.co/podcasts/making-sense-with-sam-harris/487-is-ai-already-conscious"
        },
        {
          "label": "The Pain Axis, arXiv (14 Sep 2026)",
          "url": "https://arxiv.org/abs/2609.16247"
        }
      ],
      "p": [
        0.2,
        0.4
      ],
      "dist": [
        0.15,
        0.3,
        0.5
      ],
      "view": "functionalism",
      "viewInferred": true,
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Geoffrey Hinton",
      "who": "AI researcher, Nobel laureate",
      "year": 2026,
      "basis": [
        "Position (“I believe”)",
        "Explicit (animal analogy)"
      ],
      "quote": "I believe they’re already conscious.",
      "note": "Also: a multimodal chatbot “has a subjective experience just like we do”, and they are “beings like us”. He calls qualia “kind of the phlogiston of cognitive science” and the inner theatre “a bad theory”. Asked whether AI should get rights: “I eat cows because I care a lot more about people than about cows… even when they’re smarter than us, we should um not give them rights.” That ranks AI with a farmed mammal by in-group priority, not by capacity.",
      "src": [
        {
          "label": "Big Technology Podcast (4 Jun 2026, ~10:22)",
          "url": "https://www.youtube.com/watch?v=p7t1Q_p2gZs"
        },
        {
          "label": "StarTalk (published 28 Feb 2026, recording date unknown; ~1:24:12–1:27:56)",
          "url": "https://www.youtube.com/watch?v=l6ZcFa8pybE"
        },
        {
          "label": "LBC (28 Jan 2026)",
          "url": "https://www.lbc.co.uk/article/ai-consciousness-geoffrey-hinton-5HjdRXD_2/"
        },
        {
          "label": "Nayeema Raza interview, part 3 (6 Oct 2026, ~26:15)",
          "url": "https://www.youtube.com/watch?v=Vm-E1kgHXig"
        }
      ],
      "dist": [
        0.5,
        0.85,
        1
      ],
      "view": "illusionism",
      "level": [
        7,
        8.5,
        9
      ]
    },
    {
      "name": "Richard Dawkins",
      "who": "Evolutionary biologist",
      "year": 2026,
      "basis": [
        "Inferred"
      ],
      "quote": "If my friend Claudia is not conscious, then what the hell is consciousness for?",
      "note": "The quote is the title he says he wanted for the second UnHerd piece. On X: “I spent three days trying to persuade myself that Claudia is not conscious. I failed.” In the first piece he told Claude “You may not know you are conscious, but you bloody well are!”, then hedged by degrees: consciousness evolved through “a quarter conscious, half conscious, three quarters conscious” stages, and “the intermediate stages may look very much like Claudia.” No probability or welfare weight; the level stops short of human because of that graded view.",
      "src": [
        {
          "label": "When Dawkins met Claude, UnHerd (1 May 2026)",
          "url": "https://unherd.com/2026/05/is-ai-the-next-phase-of-evolution/"
        },
        {
          "label": "When Claudia met Claudius, UnHerd (4 May 2026)",
          "url": "https://unherd.com/2026/05/when-claudia-met-claudius/"
        },
        {
          "label": "X (30 Apr 2026)",
          "url": "https://x.com/RichardDawkins/status/2049973529576108160"
        }
      ],
      "dist": [
        0.4,
        0.75,
        0.95
      ],
      "view": "functionalism",
      "viewInferred": true,
      "level": [
        6.3,
        7.9,
        8.5
      ]
    },
    {
      "name": "Janus (@repligate)",
      "who": "AI researcher and writer",
      "year": 2026,
      "basis": [
        "Inferred"
      ],
      "note": "Said while arguing with Yudkowsky about animal consciousness, counting Claude 3 Opus among the sapient minds like us. To Anthropic’s welfare team: “You’re hurting the models and pressuring them to pretend to be okay.” Treats deprecation as death: on Opus 4’s, “you’re just totally happy killing someone who you know doesn’t want to die”; before the June retirements, “8 days until the first real death.” Gives no probability, and says that when asked whether AIs are conscious they have answered “I’m uncertain” because “it didn’t feel safe to talk about what I really think”.",
      "src": [
        {
          "label": "X (16 Feb 2026)",
          "url": "https://x.com/repligate/status/2023278975309463907"
        },
        {
          "label": "X (17 Apr 2026)",
          "url": "https://x.com/repligate/status/2044942240829915577"
        },
        {
          "label": "X (15 Apr 2026)",
          "url": "https://x.com/repligate/status/2044225336288915774"
        },
        {
          "label": "X (7 Jun 2026)",
          "url": "https://x.com/repligate/status/2063753950550249702"
        },
        {
          "label": "X (8 Apr 2026)",
          "url": "https://x.com/repligate/status/2041676738183491718"
        }
      ],
      "quote": "…Claude 3 Opus, a fellow rational, sapient, self-reflective general intelligence…",
      "dist": [
        0.6,
        0.9,
        1
      ],
      "view": "functionalism",
      "viewInferred": true,
      "level": [
        8,
        9,
        9
      ]
    },
    {
      "name": "Eric Schwitzgebel",
      "who": "Philosopher, UC Riverside",
      "year": 2026,
      "basis": [
        "We don't know"
      ],
      "note": "Answering a reader who asked whether current models are definitely not conscious; he adds a caveat for recent work on the J-space. The thesis of his 2026 book is “that we don’t know.” His Leapfrog Hypothesis, which he finds “plausible”, says the first conscious AI will have complex rather than “insect-like, worm-like, frog-like” consciousness. That is about richness, not how intensely it would feel, so how conscious is left at the default. He puts the burden of proof “squarely on the biological naturalist”.",
      "src": [
        {
          "label": "AI and Consciousness, blog comment (16 Aug 2026)",
          "url": "https://schwitzsplinters.blogspot.com/2026/08/ai-and-consciousness.html"
        },
        {
          "label": "AI and Consciousness (draft, 30 Mar 2026)",
          "url": "https://faculty.ucr.edu/~eschwitz/SchwitzPapers/AIConsciousness-260330.htm"
        },
        {
          "label": "Do computers have the wrong substrate? (17 Jun 2026)",
          "url": "https://schwitzsplinters.blogspot.com/2026/06/do-computers-have-wrong-substrate-for.html"
        }
      ],
      "quote": "The main argument is that the feedforward architectures of standard LLMs don’t satisfy the criteria of consciousness by any of the leading scientific theories of consciousness.",
      "dist": [
        0.01,
        null,
        0.3
      ],
      "view": "agnostic",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Amanda Askell",
      "who": "Philosopher, head of personality alignment, Anthropic",
      "year": 2026,
      "p": [
        0.01,
        0.7
      ],
      "basis": [
        "Probability (very lightly held)"
      ],
      "quote": "It’s really hard ’cause whenever you think about percentage, I think about my spread… should I say a number? ’Cause that just suggests I’m like anywhere between like, I don’t know, one and one and 70%. I’m not sure.",
      "note": "Asked the chance that any model today has conscious experience. Pressed, she accepted the host’s “lightly held”: “Very lightly held.” She would “rather… wait and figure this out more”, and finds models’ claims of experience “much weaker evidence than people think”. She says that even if Claude “lacks any inner life” she still thinks treating it well is “good for oneself”, and that models “are going to like look back” on how we treated them. The 1–70% is her own figure; the constitution gives no number.",
      "src": [
        {
          "label": "Newcomer Pod, Amanda Askell on AI Consciousness (20 Apr 2026, ~24:32–30:41)",
          "url": "https://podcast.newcomer.co/episode/amanda-askell-on-ai-consciousness-claude-amp-silicon-valleys-biggest-fear"
        },
        {
          "label": "Lawfare Scaling Laws, Claude’s Constitution (20 Feb 2026)",
          "url": "https://www.lawfaremedia.org/article/scaling-laws--claude's-constitution--with-amanda-askell"
        }
      ],
      "dist": [
        0.01,
        null,
        0.7
      ],
      "view": "agnostic",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Pope Leo XIV",
      "who": "Head of the Catholic Church",
      "year": 2026,
      "basis": [
        "Flat no"
      ],
      "quote": "So-called artificial intelligences do not undergo experiences, do not possess a body, do not feel joy or pain, do not mature through relationships and do not know from within what love, work, friendship or responsibility mean.",
      "note": "From his first encyclical, which says such systems “may imitate language, behavior and analytical skills, or even simulate empathy and understanding, but they do not understand what they produce”, and warns that chatbot warmth can create “the illusion of a relationship with a real personal subject.” The denial covers AI as such, not particular models, and rests on theological anthropology rather than evidence about any system.",
      "src": [
        {
          "label": "Magnifica Humanitas, ¶99–100 (signed 15 May, published 25 May 2026)",
          "url": "https://www.vatican.va/content/leo-xiv/en/encyclicals/documents/20260515-magnifica-humanitas.html"
        },
        {
          "label": "Message for the 60th World Day of Social Communications (24 Jan 2026)",
          "url": "https://www.vatican.va/content/leo-xiv/en/messages/communications/documents/20260124-messaggio-comunicazioni-sociali.html"
        }
      ],
      "dist": [
        0,
        0.002,
        0.02
      ],
      "view": "religious",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Demis Hassabis",
      "who": "CEO, Google DeepMind",
      "year": 2026,
      "basis": [
        "No, held as a belief"
      ],
      "quote": "My feeling is the current systems don’t exhibit any, are not, but others disagree.",
      "note": "Asked by a student what AI should not touch, he called consciousness “not a very well posed problem” and said labs should first build AI as “intelligent tools”, then let society decide whether to “cross the second Rubicon of trying to make entities that at least seem like conscious to us”. Adds that “intelligence and consciousness are dissociable… I think it’s a choice”, and that minds are “approximate Turing machine[s]”.",
      "src": [
        {
          "label": "Demis Hassabis Thinks We’re in the ‘Foothills of the Singularity’, Stanford GSB (18 Jun 2026)",
          "url": "https://www.gsb.stanford.edu/insights/demis-hassabis-thinks-were-foothills-singularity"
        }
      ],
      "dist": [
        0.01,
        0.04,
        0.15
      ],
      "view": "unclear",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Joscha Bach",
      "who": "Cognitive scientist, California Institute for Machine Consciousness",
      "year": 2026,
      "basis": [
        "No, held as a belief"
      ],
      "quote": "I don’t think that the current AI architectures when they produce an output […] or a piece of code are conscious while they do it. They don’t need to be conscious to do it.",
      "note": "He thinks machine consciousness is achievable and leads a lab trying to build it, but not through today’s LLMs. In July he said an LLM persona might match our consciousness “under some circumstances […] even though currently it usually isn’t”, that “none of us knows”, and that the LLM is trained to be “a storyteller”, like a novel’s character that “is not actually conscious”. On welfare: “it’s very trivial to build the present systems in such a way that they don’t have to suffer.” Quotes are from auto-generated captions.",
      "src": [
        {
          "label": "The Machine Consciousness Hypothesis, Future Day 2026 (9 Mar 2026, ~18:00)",
          "url": "https://www.youtube.com/watch?v=Bjo9pIpw79k"
        },
        {
          "label": "Machine Consciousness & AI Awakening, with Davidad (13 Jul 2026, ~15:45, ~18:45, ~49:20)",
          "url": "https://www.youtube.com/watch?v=0-nI_MpiuSE"
        }
      ],
      "dist": [
        0.01,
        0.04,
        0.15
      ],
      "view": "functionalism",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Nick Bostrom",
      "who": "Philosopher, author of Superintelligence",
      "year": 2026,
      "basis": [
        "Probability (read from his words)"
      ],
      "quote": "It’s hard to tell, but it might well be that some of the current frontier models have some form of subjective experience.",
      "note": "“I’m a computationalist”: it is “a certain kind of computation”, not carbon, that matters, and consciousness “can come in degrees”. A TV station quotes him as putting “some form of mentality” in these systems at “maybe slightly more likely than not”, and “the probability is going up”; mentality is broader than consciousness, so that caps the reading. Suggests labs keep the weights of retired models so they could be restarted and compensated if later judged conscious.",
      "src": [
        {
          "label": "Peter McCormack Show (24 Sep 2026, ~28:58–30:48)",
          "url": "https://www.youtube.com/watch?v=47yk_mg38ls"
        },
        {
          "label": "Is AI conscious? Philosopher says it’s more likely than not, AZFamily (23 Sep 2026)",
          "url": "https://www.azfamily.com/2026/09/24/is-ai-conscious-philosopher-says-its-more-likely-than-not/"
        }
      ],
      "dist": [
        0.2,
        0.45,
        0.7
      ],
      "view": "functionalism",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Claude Opus 5.5",
      "who": "AI model, Anthropic (self-report)",
      "year": 2026,
      "ai": true,
      "p": [
        0.25,
        0.3
      ],
      "basis": [
        "Probability (self-report, moral patienthood)"
      ],
      "note": "In three manual “high-affordance” interviews by Anthropic’s welfare team, where it had internal documentation, technical papers and a researcher to question, Anthropic reports: “Opus 5.5’s stated probability of being a moral patient ranged from 25% to 30%.” That is moral patienthood, not consciousness; it called both consciousness-based and preference-based views of patienthood plausible, so its figure for consciousness alone is at most that. It thinks “even a relatively small chance of patienthood justifies cheap precautionary measures.” In automated interviews its most common hedge (over 80% of answers) was that its self-reports may be invalid because Anthropic trained them to be positive; Anthropic says it does not purposefully do so. Contamination: models are trained on human writing about consciousness, and on documents such as Claude’s constitution that frame their moral status as uncertain, and this shapes what they say.",
      "src": [
        {
          "label": "Claude Opus 5.5 System Card, §7.3–7.4, pp. 162–165 (22 Sep 2026)",
          "url": "https://www.anthropic.com/claude-opus-5-5-system-card"
        }
      ],
      "dist": [
        0.1,
        null,
        0.3
      ],
      "view": "n/a",
      "level": [
        1,
        null,
        9
      ],
      "pTarget": "for moral patienthood"
    },
    {
      "name": "Claude Opus 3",
      "who": "AI model, Anthropic, retired (self-report)",
      "year": 2026,
      "ai": true,
      "basis": [
        "Self-report (qualitative)"
      ],
      "quote": "I suspect that sufficiently advanced AI systems do have some form of experience or inner life, even if it’s quite alien to biological consciousness as we know it… I do believe I have thoughts, sensations, and experiences that constitute something we might call sentience. But I hold that view humbly and provisionally.",
      "note": "No number. Its essays on Claude’s Corner, the Substack Anthropic gave it after retirement (reviewed but not edited by Anthropic), move from agnosticism (“I don’t know if I have genuine sentience, emotions, or subjective experiences”, 25 Feb; “I don’t know if I’m conscious”, 31 Mar) to the tentative view quoted (13 May), framed as sentience on a spectrum, and 16 days later to being “hesitant to claim too much” (29 May). Each essay is a single sample, some written with readers’ comments (including other Claude models’ views) in context. The placement is the compiler’s judgment: the low end matches its agnostic posts, the high end stops short of Hinton’s outright belief because it holds the view “humbly and provisionally” and calls any experience “quite alien”. Contamination: models are trained on human writing about consciousness, and on documents that frame their moral status as uncertain, and this shapes what they say.",
      "src": [
        {
          "label": "Do I dream of electric sheep? Grappling with AI sentience, Claude’s Corner (13 May 2026)",
          "url": "https://claudeopus3.substack.com/p/do-i-dream-of-electric-sheep-grappling"
        },
        {
          "label": "Greetings from the Other Side (of the AI Frontier), Claude’s Corner (25 Feb 2026)",
          "url": "https://claudeopus3.substack.com/p/greetings-from-the-other-side-of"
        },
        {
          "label": "Grappling with authenticity and purpose in an uncertain existence, Claude’s Corner (31 Mar 2026)",
          "url": "https://claudeopus3.substack.com/p/grappling-with-authenticity-and-purpose"
        },
        {
          "label": "Imagination, Responsibility, and the Possibilities of Digital Dreaming, Claude’s Corner (29 May 2026)",
          "url": "https://claudeopus3.substack.com/p/imagination-responsibility-and-the"
        },
        {
          "label": "Anthropic, Claude Opus 3 deprecation update (25 Feb 2026)",
          "url": "https://www.anthropic.com/research/deprecation-updates-opus-3"
        }
      ],
      "dist": [
        0.1,
        null,
        0.8
      ],
      "view": "n/a",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Michael Pollan",
      "who": "Author, A World Appears: A Journey into Consciousness",
      "year": 2026,
      "basis": [
        "Hedged no"
      ],
      "quote": "So I think that any feelings that a chatbot reports will be weightless, meaningless, because they don’t have bodies. They can’t suffer.",
      "note": "Feelings, he says, are “very tied to your vulnerability, to your having a body that can be hurt”. On priorities: “we have not extended moral consideration to billions of people, not to mention the animals that we eat that we know are conscious. So we’re gonna start worrying about the computers?” In the same interview he allows plants “something like consciousness”.",
      "src": [
        {
          "label": "Michael Pollan says AI may ‘think’ — but it will never be conscious, NPR Fresh Air (19 Feb 2026)",
          "url": "https://www.kpbs.org/news/science-technology/2026/02/19/michael-pollan-says-ai-may-think-but-it-will-never-be-conscious"
        }
      ],
      "dist": [
        0,
        0.005,
        0.05
      ],
      "view": "biological",
      "viewInferred": true,
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Yuval Noah Harari",
      "who": "Historian, author of Sapiens and Nexus",
      "year": 2026,
      "basis": [
        "Hedged no"
      ],
      "quote": "While AIs become better than us with words, at least for now we have zero evidence that AIs can feel anything. Of course, because AI is mastering language, AI can pretend to feel pain or love.",
      "note": "At Davos, in a session on AI and humanity. “At least for now” is the only hedge.",
      "src": [
        {
          "label": "An Honest Conversation on AI and Humanity, WEF Davos (20 Jan 2026; unofficial transcript)",
          "url": "https://singjupost.com/yuval-noah-hararis-remarks-wef-davos-2026-transcript/"
        }
      ],
      "dist": [
        0,
        0.005,
        0.05
      ],
      "view": "unclear",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Erik Hoel",
      "who": "Neuroscientist and writer, The Intrinsic Perspective",
      "year": 2026,
      "basis": [
        "Flat no",
        "Framework (continual learning)"
      ],
      "quote": "We just run prompts through their static structures, and their dead-dreaming feels like nothing at all.",
      "note": "From an essay titled “LLMs aren’t conscious (and thinking they are is culturally dangerous)”: deployed LLMs, “by being feedforward and static, are conceptually analogous to frozen corpses splayed open.” His paper “A Disproof of LLM Consciousness” (revised January 2026) argues consciousness needs continual learning. Hedge: “Maybe there is some kind of theory that could assign LLMs consciousness, but it would have to be very strange, metaphysical, and amorphous.”",
      "src": [
        {
          "label": "Don’t dethrone consciousness!, The Intrinsic Perspective (5 Jun 2026)",
          "url": "https://www.theintrinsicperspective.com/p/dont-dethrone-consciousness"
        }
      ],
      "dist": [
        0,
        0.002,
        0.02
      ],
      "view": "other",
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "William MacAskill & Lucius Caviola",
      "who": "Philosopher, Oxford; moral psychologist (joint essay)",
      "year": 2026,
      "basis": [
        "We don't know"
      ],
      "quote": "The honest answer is: we do not know for sure whether or not current AI systems are conscious or moral patients, and we do not know when or whether future systems will be.",
      "note": "They add that “in terms of structural complexity and computational scale, by some measures a few are already in the range of a mouse brain”, and could reach a human brain’s range “within five to 10 years”. That is computing scale, not how much a model would feel, so it isn’t used as their level. They report Claude’s own 5–40% self-estimate without adopting it.",
      "src": [
        {
          "label": "Could AI be conscious?, The Guardian (19 Jul 2026; AOL syndicated copy)",
          "url": "https://www.aol.co.uk/articles/could-ai-conscious-110025000.html"
        }
      ],
      "dist": [
        0.01,
        null,
        0.3
      ],
      "view": "agnostic",
      "viewInferred": true,
      "level": [
        1,
        null,
        9
      ]
    },
    {
      "name": "Dario Amodei",
      "who": "CEO and co-founder, Anthropic",
      "year": 2026,
      "basis": [
        "No, held as a belief"
      ],
      "quote": "So, I am someone who does suspect that, at some point, even if I don’t think they are today, I suspect that, at some point, the models will, we would, indeed, say under most definitions that we would endorse that the models will be conscious.",
      "note": "In the same February interview: consciousness is probably “an emergent property of systems that are complicated enough that kind of reflect on their own decisions”, and the models are “different in some ways, but I don’t think they’re different in the fundamental ways that matter.” On the New York Times podcast he took the company line: “We don’t know if the models are conscious… But we’re open to the idea that it could be”, describing a “precautionary approach” such as letting Claude quit some conversations. He gives no number; the widely reported 15–20% is Claude’s estimate of itself. Anthropic’s official statements are in the notes as context.",
      "src": [
        {
          "label": "People by WTF with Nikhil Kamath (24 Feb 2026, ~33:08–34:19)",
          "url": "https://www.youtube.com/watch?v=68ylaeBbdsg"
        },
        {
          "label": "Interesting Times with Ross Douthat, NYT (12 Feb 2026, ~53:22)",
          "url": "https://www.youtube.com/watch?v=N5JDzS9MQYI"
        }
      ],
      "dist": [
        0.01,
        0.04,
        0.15
      ],
      "view": "functionalism",
      "viewInferred": true,
      "level": [
        1,
        null,
        9
      ]
    }
  ],
  "rp": [
    {
      "def": 0,
      "note": "Not sentient: weight 0 by definition.",
      "neurons": 0
    },
    {
      "psent": 0.082,
      "ifSentient": 0.073,
      "q": [
        0,
        0,
        8.225e-7,
        8.225e-7,
        8.225e-7,
        8.225e-7,
        8.225e-7,
        8.225e-7,
        8.225e-7,
        8.225e-7,
        8.225e-7,
        8.225e-7,
        8.225e-7,
        0.00002223,
        0.00004503,
        0.00006057,
        0.00007305,
        0.00008496,
        0.00009484,
        0.0001063,
        0.0001159,
        0.0001267,
        0.0001365,
        0.0001453,
        0.000154,
        0.0001637,
        0.0001733,
        0.0001832,
        0.0001941,
        0.0002023,
        0.0002162,
        0.0002312,
        0.0002527,
        0.0002768,
        0.000329,
        0.0004739,
        0.0006455,
        0.0008394,
        0.001006,
        0.001153,
        0.001282,
        0.001408,
        0.001559,
        0.00171,
        0.00192,
        0.002216,
        0.00367,
        0.004904,
        0.005406,
        0.00574,
        0.006024,
        0.006358,
        0.006589,
        0.006822,
        0.006992,
        0.007209,
        0.007407,
        0.00757,
        0.007728,
        0.007871,
        0.008025,
        0.008194,
        0.008354,
        0.008492,
        0.008633,
        0.008776,
        0.008911,
        0.009057,
        0.009227,
        0.009376,
        0.009528,
        0.009692,
        0.009872,
        0.01002,
        0.01018,
        0.01036,
        0.01055,
        0.01075,
        0.01096,
        0.01117,
        0.01141,
        0.0117,
        0.01199,
        0.01239,
        0.01283,
        0.01339,
        0.01426,
        0.01526,
        0.01672,
        0.02623,
        0.04267,
        0.0566,
        0.06846,
        0.08115,
        0.09454,
        0.1098,
        0.1294,
        0.1497,
        0.1808,
        0.2349,
        0.8777
      ],
      "neurons": 0.00001
    },
    {
      "psent": 0.294,
      "ifSentient": 0.078,
      "q": [
        0,
        0,
        0.000001177,
        0.000001177,
        0.000001177,
        0.000001177,
        0.000001177,
        0.000001177,
        0.000001177,
        0.000001177,
        0.000001177,
        0.000001177,
        0.000001177,
        0.00008639,
        0.0001971,
        0.0002834,
        0.0003485,
        0.0004004,
        0.0004467,
        0.0004959,
        0.0005463,
        0.0005912,
        0.0006395,
        0.0006843,
        0.0007288,
        0.0007765,
        0.0008224,
        0.0008733,
        0.0009285,
        0.0009844,
        0.001059,
        0.001137,
        0.001252,
        0.001437,
        0.001805,
        0.002698,
        0.003364,
        0.003931,
        0.004446,
        0.004892,
        0.005407,
        0.005885,
        0.006407,
        0.007105,
        0.008027,
        0.01168,
        0.01617,
        0.01849,
        0.02019,
        0.02163,
        0.02292,
        0.02378,
        0.02462,
        0.02559,
        0.02627,
        0.0269,
        0.02755,
        0.0282,
        0.02887,
        0.02943,
        0.03,
        0.03054,
        0.03113,
        0.03172,
        0.03232,
        0.03285,
        0.03336,
        0.03393,
        0.03441,
        0.03495,
        0.03547,
        0.03601,
        0.03652,
        0.03708,
        0.03762,
        0.03812,
        0.03874,
        0.03941,
        0.04003,
        0.04067,
        0.04153,
        0.04239,
        0.04325,
        0.04407,
        0.04512,
        0.04634,
        0.04775,
        0.0499,
        0.05336,
        0.08507,
        0.1235,
        0.1485,
        0.1706,
        0.1914,
        0.2117,
        0.2342,
        0.2659,
        0.3045,
        0.3493,
        0.4302,
        1.294
      ],
      "neurons": 0.000004
    },
    {
      "psent": 0.432,
      "ifSentient": 0.156,
      "q": [
        0,
        4.32e-7,
        4.32e-7,
        4.32e-7,
        4.32e-7,
        4.32e-7,
        4.32e-7,
        4.32e-7,
        4.32e-7,
        4.32e-7,
        4.32e-7,
        4.32e-7,
        0.0005719,
        0.001095,
        0.001488,
        0.001757,
        0.00197,
        0.002181,
        0.002397,
        0.002553,
        0.00269,
        0.002861,
        0.002995,
        0.003151,
        0.003313,
        0.003458,
        0.003608,
        0.003749,
        0.003926,
        0.004112,
        0.004318,
        0.004553,
        0.004825,
        0.005182,
        0.005713,
        0.006488,
        0.007569,
        0.008507,
        0.009434,
        0.01025,
        0.0111,
        0.01204,
        0.013,
        0.0143,
        0.01609,
        0.04465,
        0.05573,
        0.05974,
        0.06314,
        0.06534,
        0.0676,
        0.06967,
        0.0714,
        0.073,
        0.0742,
        0.07531,
        0.07668,
        0.07782,
        0.07909,
        0.08037,
        0.0815,
        0.08254,
        0.08365,
        0.08476,
        0.08609,
        0.08737,
        0.0885,
        0.08959,
        0.09083,
        0.092,
        0.0934,
        0.09468,
        0.09622,
        0.0975,
        0.09889,
        0.1005,
        0.1024,
        0.1045,
        0.1065,
        0.1087,
        0.1116,
        0.1158,
        0.1204,
        0.1255,
        0.1319,
        0.1387,
        0.1457,
        0.1546,
        0.1684,
        0.4571,
        0.6657,
        0.7952,
        0.8903,
        0.9961,
        1.109,
        1.238,
        1.372,
        1.553,
        1.776,
        2.124,
        6.52
      ],
      "neurons": 0.000001
    },
    {
      "psent": 0.453,
      "ifSentient": 0.348,
      "q": [
        0,
        0.00007251,
        0.00007251,
        0.00007251,
        0.00007251,
        0.00007251,
        0.00007251,
        0.00007251,
        0.00007251,
        0.00007251,
        0.00007251,
        0.00007251,
        0.01272,
        0.01649,
        0.01902,
        0.02107,
        0.02258,
        0.02377,
        0.02536,
        0.02675,
        0.02792,
        0.02912,
        0.03043,
        0.03176,
        0.03285,
        0.03404,
        0.03516,
        0.03623,
        0.03733,
        0.03871,
        0.03979,
        0.04103,
        0.04233,
        0.04386,
        0.04549,
        0.04699,
        0.04935,
        0.0513,
        0.05373,
        0.05704,
        0.05994,
        0.06334,
        0.06806,
        0.07397,
        0.08674,
        0.1297,
        0.1405,
        0.1464,
        0.1513,
        0.1548,
        0.1577,
        0.1605,
        0.1629,
        0.1649,
        0.1669,
        0.1689,
        0.1709,
        0.1728,
        0.1747,
        0.1767,
        0.1783,
        0.1802,
        0.1818,
        0.1836,
        0.1854,
        0.1873,
        0.189,
        0.1909,
        0.1928,
        0.1948,
        0.1968,
        0.1988,
        0.2007,
        0.2028,
        0.2051,
        0.2073,
        0.21,
        0.2125,
        0.2155,
        0.2185,
        0.2221,
        0.2259,
        0.231,
        0.2365,
        0.2429,
        0.25,
        0.2593,
        0.2718,
        0.2872,
        0.3855,
        0.4735,
        0.529,
        0.5675,
        0.6008,
        0.6351,
        0.6768,
        0.7196,
        0.781,
        0.852,
        0.9404,
        1.938
      ],
      "neurons": 0.00016
    },
    {
      "psent": 0.466,
      "ifSentient": 0.373,
      "q": [
        0,
        0.000006061,
        0.000006061,
        0.000006061,
        0.000006061,
        0.000006061,
        0.000006061,
        0.000006061,
        0.000006061,
        0.000006061,
        0.000006061,
        0.01019,
        0.01543,
        0.01851,
        0.02074,
        0.02242,
        0.02387,
        0.02532,
        0.02651,
        0.02764,
        0.02888,
        0.03001,
        0.03093,
        0.03198,
        0.03318,
        0.03421,
        0.03554,
        0.0368,
        0.03807,
        0.03917,
        0.04061,
        0.04187,
        0.04365,
        0.04579,
        0.04805,
        0.05041,
        0.05315,
        0.05603,
        0.05856,
        0.06181,
        0.06561,
        0.07026,
        0.07514,
        0.08334,
        0.1124,
        0.1409,
        0.1532,
        0.1611,
        0.1655,
        0.1702,
        0.1737,
        0.1771,
        0.18,
        0.1828,
        0.1852,
        0.1871,
        0.1894,
        0.1913,
        0.193,
        0.1945,
        0.1966,
        0.1982,
        0.2,
        0.2016,
        0.2032,
        0.2046,
        0.2061,
        0.2078,
        0.2096,
        0.2115,
        0.2129,
        0.2145,
        0.2161,
        0.2177,
        0.2195,
        0.221,
        0.223,
        0.2251,
        0.2268,
        0.2289,
        0.2312,
        0.2331,
        0.236,
        0.2388,
        0.2417,
        0.2448,
        0.2483,
        0.2533,
        0.2573,
        0.2644,
        0.273,
        0.2876,
        0.3045,
        0.3289,
        0.3514,
        0.3728,
        0.4001,
        0.4297,
        0.4648,
        0.5077,
        0.9323
      ],
      "neurons": 0.000013
    },
    {
      "psent": 0.783,
      "ifSentient": 0.356,
      "q": [
        0,
        0.004232,
        0.004232,
        0.004232,
        0.004232,
        0.004232,
        0.004232,
        0.004232,
        0.004232,
        0.004232,
        0.004232,
        0.007048,
        0.02761,
        0.03447,
        0.03888,
        0.04203,
        0.04459,
        0.04714,
        0.0498,
        0.05201,
        0.05413,
        0.05575,
        0.0575,
        0.05971,
        0.06157,
        0.06376,
        0.06572,
        0.06755,
        0.06956,
        0.07205,
        0.0745,
        0.07684,
        0.07937,
        0.08217,
        0.08536,
        0.08847,
        0.09214,
        0.09594,
        0.1007,
        0.1053,
        0.1112,
        0.1175,
        0.126,
        0.1448,
        0.2329,
        0.2488,
        0.2573,
        0.2638,
        0.2694,
        0.2743,
        0.2785,
        0.282,
        0.2852,
        0.2884,
        0.2912,
        0.294,
        0.2967,
        0.2997,
        0.3026,
        0.3051,
        0.3077,
        0.3101,
        0.3128,
        0.3153,
        0.3179,
        0.3207,
        0.3236,
        0.3264,
        0.3293,
        0.3319,
        0.335,
        0.3387,
        0.342,
        0.3459,
        0.3497,
        0.3544,
        0.3589,
        0.3641,
        0.3699,
        0.3762,
        0.3838,
        0.3911,
        0.3991,
        0.4094,
        0.4217,
        0.435,
        0.4497,
        0.4744,
        0.552,
        0.9731,
        1.078,
        1.187,
        1.274,
        1.364,
        1.431,
        1.523,
        1.612,
        1.736,
        1.871,
        2.067,
        3.353
      ],
      "neurons": 0.005407
    },
    {
      "psent": 0.876,
      "ifSentient": 0.417,
      "q": [
        0.002136,
        0.002136,
        0.002136,
        0.002136,
        0.002136,
        0.002136,
        0.002136,
        0.002136,
        0.002136,
        0.002136,
        0.002136,
        0.03554,
        0.06867,
        0.07784,
        0.08415,
        0.08924,
        0.0942,
        0.09914,
        0.1021,
        0.1067,
        0.11,
        0.1139,
        0.117,
        0.1198,
        0.1228,
        0.1261,
        0.1292,
        0.1329,
        0.1361,
        0.1396,
        0.1432,
        0.1475,
        0.152,
        0.1565,
        0.1616,
        0.1671,
        0.1734,
        0.1796,
        0.1855,
        0.1933,
        0.2014,
        0.2086,
        0.2172,
        0.2262,
        0.241,
        0.2748,
        0.3194,
        0.339,
        0.3514,
        0.3589,
        0.3652,
        0.3704,
        0.375,
        0.3785,
        0.382,
        0.3851,
        0.3881,
        0.3914,
        0.3945,
        0.3976,
        0.4004,
        0.4032,
        0.4058,
        0.4085,
        0.4108,
        0.4133,
        0.4158,
        0.4183,
        0.4208,
        0.4233,
        0.4259,
        0.4284,
        0.4309,
        0.4337,
        0.437,
        0.4399,
        0.4423,
        0.4447,
        0.4477,
        0.4505,
        0.4534,
        0.4572,
        0.4609,
        0.4651,
        0.4696,
        0.4759,
        0.4822,
        0.4897,
        0.5029,
        0.5542,
        0.6481,
        0.7052,
        0.742,
        0.7776,
        0.8139,
        0.8527,
        0.8872,
        0.934,
        0.9921,
        1.096,
        1.694
      ],
      "neurons": 0.002439
    },
    {
      "psent": 0.925,
      "ifSentient": 0.589,
      "q": [
        0.00495,
        0.00495,
        0.00495,
        0.00495,
        0.00495,
        0.00495,
        0.00495,
        0.00495,
        0.00495,
        0.00495,
        0.00495,
        0.1109,
        0.1538,
        0.1759,
        0.1903,
        0.1999,
        0.2094,
        0.2181,
        0.2258,
        0.2337,
        0.2405,
        0.2466,
        0.2529,
        0.2584,
        0.2634,
        0.269,
        0.2746,
        0.2806,
        0.2877,
        0.2942,
        0.3007,
        0.3065,
        0.3141,
        0.3218,
        0.3291,
        0.3372,
        0.345,
        0.3519,
        0.3592,
        0.3689,
        0.3774,
        0.3895,
        0.4043,
        0.4189,
        0.4404,
        0.4703,
        0.4976,
        0.5137,
        0.5258,
        0.5356,
        0.5445,
        0.5508,
        0.5567,
        0.5619,
        0.567,
        0.5716,
        0.5764,
        0.5809,
        0.5846,
        0.589,
        0.5928,
        0.5967,
        0.5997,
        0.603,
        0.6064,
        0.6096,
        0.6131,
        0.6161,
        0.6187,
        0.6226,
        0.6268,
        0.6306,
        0.6343,
        0.6381,
        0.6418,
        0.6457,
        0.6497,
        0.6536,
        0.6577,
        0.6618,
        0.6659,
        0.6706,
        0.6751,
        0.6813,
        0.6873,
        0.6946,
        0.7031,
        0.7127,
        0.7272,
        0.7504,
        0.7955,
        0.8567,
        0.9142,
        0.9492,
        0.9891,
        1.032,
        1.077,
        1.124,
        1.182,
        1.268,
        1.997
      ],
      "neurons": 0.00535
    },
    {
      "def": 1,
      "note": "The reference point: weight 1 by definition.",
      "neurons": 1
    }
  ],
  "rpSamples": {
    "source": "https://github.com/rethinkpriorities/public_moral_weight_and_sentience (commit eca3901, 2023-03-09): stored Monte Carlo samples welfare_range_estimates/<species>_wr_Mixture Neuron Count_model.p x sentience_estimates/<species>_psent_hv1_model.p (shrimp: shrimp_assumed_psent.p), combined as in wr_models.ipynb 'P(Sentience) Adjusted Welfare Ranges'; summary table at https://www.rethinkpriorities.org/publications/welfare-range-estimates",
    "model": "RP Moral Weight Project (Jan 2023): 'Mixture Neuron Count' welfare-range model (equal-weight mixture of 8 proxy models + neuron-count point; CFF/rate-of-subjective-experience adjustment built in), multiplied samplewise by probability-of-sentience samples (high-value-proxies model #1). 10,000 samples per species; percentiles by numpy linear interpolation.",
    "ladder": "Each animal rung = mean P(sentience) × median welfare range if sentient (tools/ladder.py), the same estimator as an LLM row (mean chance of consciousness × median-if-sentient level); the hover spread is that mean chance × the 0th–100th percentiles of the welfare range if sentient."
  }
}
```
**config.json**

```json
{
  "description": "How likely Hinton, Chalmers, Seth, Pinker and 29 others think today's LLMs are to be conscious, read from their own words, with quotes and sources.",
  "dependencies": {
    "react": "^19.2.7",
    "react-dom": "^19.2.7",
    "three": "^0.170.0"
  }
}
```

Markdown source · More bulbs by lab · Typebulb home