spb/airiskindex Public
The most methodologically rigorous, fully transparent AI job-exposure index.
TypeScript 88%
Python 6.1%
SQL 2.7%
CSS 1.2%
JavaScript 0.9%
Shell 0.8%
1// File: page.tsx2// Path: apps/web/app/methodology/page.tsx3// Project: AI Risk Index — airiskindex.io4// Author: Simon-Pierre Boucher5// Contact: contact@spboucher.ai6// Copyright © 2026 Simon-Pierre Boucher. All rights reserved.7//8// Description: Human-readable methodology documentation (weights pulled live from the engine).910import Link from "next/link";11import {12 DIMENSIONS,13 EXPOSURE_DIMENSIONS,14 HIGH_EXPOSURE_THRESHOLD,15 INDEX_VERSION,16 INVERTED_DIMENSIONS,17 WEIGHTS,18 type DimensionKey,19} from "@airiskindex/scoring";2021export const metadata = {22 title: "Methodology — AI Risk Index",23 description:24 "Full methodology of the AI Risk Index: task-based scoring, multi-model LLM rater panel, confidence intervals, weights, formulas, versioning and limitations.",25};2627const DIMENSION_DETAILS: Array<{28 key: DimensionKey;29 name: string;30 question: string;31 anchors: string;32}> = [33 {34 key: "automatability",35 name: "Task automatability",36 question:37 "Could current AI (including tool-using agents) perform this task end-to-end with at least 50% time saving at equal quality?",38 anchors:39 "1 = no meaningful part automatable today · 3 = roughly half automatable with significant setup · 5 = the full task meets the ≥50%-time-saving-at-equal-quality bar with off-the-shelf systems. The 50% threshold follows Eloundou et al. (2024), the citable standard.",40 },41 {42 key: "feasibility",43 name: "Current technical feasibility",44 question:45 "Do deployed products demonstrably perform this task reliably today — not merely in demos or benchmarks?",46 anchors:47 "1 = research-stage only · 3 = products exist with material error rates or narrow scope · 5 = mature products perform this reliably in production at scale. Separating conceivable from deployable is the failure that undid whole-occupation forecasts.",48 },49 {50 key: "cost_ratio",51 name: "Cost of substitution vs. wage",52 question:53 "How does the all-in AI cost per task-equivalent (inference, integration, oversight) compare to the loaded human wage for the same output?",54 anchors:55 "1 = AI is more expensive all-in · 3 = roughly comparable · 5 = AI is at least an order of magnitude cheaper.",56 },57 {58 key: "barriers",59 name: "Adoption barriers",60 question:61 "How strong are the real-world barriers to substitution: licensing and authorization requirements, liability and error-cost asymmetry, regulation of the automation itself, human-contact requirements, organizational friction?",62 anchors:63 "1 = nothing prevents substitution · 3 = some friction (oversight requirements, customer preference for humans) · 5 = hard barriers — a licensed human must legally perform or sign off on the task. This dimension is inverted in the composite: strong barriers lower the substitution score.",64 },65 {66 key: "adoption_velocity",67 name: "Sector adoption velocity",68 question:69 "How fast and deep are the sectors where this task occurs actually adopting AI — agents in production and measured displacement, not vendor announcements?",70 anchors:71 "1 = laggard sectors (small firms, physical work, low digitization) · 3 = pilots common, production rare · 5 = fast, deep adoption (information, finance, professional-services patterns).",72 },73];7475function Section({76 id,77 title,78 children,79}: {80 id: string;81 title: string;82 children: React.ReactNode;83}): JSX.Element {84 return (85 <section id={id} className="mt-12 scroll-mt-6">86 <h2 className="text-2xl font-semibold tracking-tight">{title}</h2>87 <div className="mt-4 space-y-4 leading-relaxed text-[var(--ink-2)]">{children}</div>88 </section>89 );90}9192export default function MethodologyPage(): JSX.Element {93 return (94 <main className="mx-auto max-w-3xl px-4 py-10 sm:px-6 sm:py-14">95 <p className="text-xs font-semibold uppercase tracking-[0.14em] text-[var(--muted)]">96 Methodology · version {INDEX_VERSION}97 </p>98 <h1 className="mt-3 text-4xl font-bold tracking-tight">99 How the AI Risk Index is computed100 </h1>101 <p className="mt-4 text-lg leading-relaxed text-[var(--ink-2)]">102 Every number on this site is reproducible: the weights, formulas, rater prompts and every103 individual model rating are public. This page is the human-readable specification; the104 machine-readable version is at{" "}105 <Link href="/api/v1/methodology" className="underline">106 /api/v1/methodology107 </Link>108 .109 </p>110111 <nav className="mt-8 card p-5 text-sm">112 <p className="font-medium text-[var(--ink)]">Contents</p>113 <ol className="mt-2 list-inside list-decimal space-y-1 text-[var(--ink-2)]">114 {[115 ["principles", "Principles"],116 ["three-scores", "The three scores"],117 ["data", "Data sources"],118 ["rating", "Task rating — the multi-model panel"],119 ["dimensions", "The five dimensions and their weights"],120 ["formulas", "Formulas"],121 ["aggregation", "From tasks to occupations"],122 ["uncertainty", "Confidence intervals"],123 ["versioning", "Versioning and immutable runs"],124 ["validation", "Validation and sensitivity"],125 ["limitations", "Known limitations"],126 ["citation", "Citation, license and contact"],127 ].map(([anchor, label]) => (128 <li key={anchor}>129 <a href={`#${anchor}`} className="hover:text-[var(--ink)] hover:underline">130 {label}131 </a>132 </li>133 ))}134 </ol>135 </nav>136137 <Section id="principles" title="1. Principles">138 <p>139 <strong className="text-[var(--ink)]">Task-based, not occupation-based.</strong>{" "}140 Occupations are bundles of tasks with very different AI exposure. Scoring whole141 occupations with a single judgment — the approach of the famous 2013 "47% of jobs"142 estimate — has a poor empirical track record. We score each of the ~18,800 O*NET task143 statements individually and derive occupation scores from them, weighted by how144 important each task is to the occupation.145 </p>146 <p>147 <strong className="text-[var(--ink)]">Uncertainty is part of the score.</strong> Large148 language models disagree with each other substantially when rating AI exposure —149 replications show the share of "highly exposed" occupations can vary by an order of150 magnitude depending on which frontier model does the rating. A single-model index is151 therefore an artifact. Every score we publish carries a confidence interval derived from152 disagreement across an independent multi-model panel.153 </p>154 <p>155 <strong className="text-[var(--ink)]">Fully reproducible.</strong> Weights live in one156 versioned source file, prompts are versioned, every rating stores the model, prompt157 version, raw response and parsed score, and every published number traces to a stored,158 immutable computation run.159 </p>160 <p>161 <strong className="text-[var(--ink)]">Adaptation, not doom.</strong> The evidence to162 date shows concentrated, cohort-specific effects — especially on entry-level hiring in163 automation-exposed occupations — rather than economy-wide job loss, while measured AI164 usage remains majority-augmentative. The index is designed to guide adaptation165 decisions, not to produce headlines.166 </p>167 </Section>168169 <Section id="three-scores" title="2. The three scores">170 <p>Every occupation gets three sub-scores on a 0–100 scale, never collapsed into one:</p>171 <ul className="list-inside list-disc space-y-2">172 <li>173 <strong className="text-[var(--ink)]">Exposure</strong> — AI is technically capable of174 performing the occupation's tasks. Computed from the capability dimensions only175 (automatability and feasibility).176 </li>177 <li>178 <strong className="text-[var(--ink)]">Substitution</strong> — the headline composite:179 AI actually replaces the human, once cost, adoption barriers and sector adoption180 velocity are accounted for. Exposure without adoption predicts nothing; this score is181 exposure discounted by the real world.182 </li>183 <li>184 <strong className="text-[var(--ink)]">Augmentation</strong> — AI assists the human on185 the task, raising productivity without replacing them. Rated separately per task; it186 is not part of the substitution composite. High augmentation alongside moderate187 substitution reads as a changing job, not a disappearing one.188 </li>189 </ul>190 </Section>191192 <Section id="data" title="3. Data sources">193 <div className="overflow-x-auto card">194 <table className="w-full text-left text-sm">195 <thead className="border-b border-[var(--grid)] text-xs uppercase tracking-wide text-[var(--muted)]">196 <tr>197 <th className="px-4 py-3 font-medium">Input</th>198 <th className="px-4 py-3 font-medium">Source</th>199 <th className="px-4 py-3 font-medium">Role</th>200 </tr>201 </thead>202 <tbody>203 {[204 [205 "Occupations & task statements",206 "O*NET 30.3 (U.S. Dept. of Labor, CC BY 4.0), O*NET-SOC 2019 taxonomy",207 "Unit of analysis: 1,016 occupations, ~18,800 tasks",208 ],209 [210 "Task importance weights",211 "O*NET Task Ratings, importance scale (IM, 1–5)",212 "Aggregation weights from tasks to occupations",213 ],214 [215 "Wages & employment",216 "BLS Occupational Employment and Wage Statistics, May 2025 national",217 "Median wages (shown per occupation; cost-ratio context)",218 ],219 [220 "EU/France crosswalk (planned)",221 "ESCO v1.2 + official ESCO↔O*NET crosswalk; ROME 4.0",222 "European occupation coverage in a future release",223 ],224 [225 "Adoption evidence",226 "Census BTOS, Anthropic Economic Index, sector deployment studies",227 "Grounding for the adoption-velocity rubric anchors",228 ],229 ].map(([a, b, c]) => (230 <tr key={a as string} className="border-b border-[var(--grid)] last:border-b-0 align-top">231 <td className="px-4 py-3 font-medium text-[var(--ink)]">{a}</td>232 <td className="px-4 py-3">{b}</td>233 <td className="px-4 py-3">{c}</td>234 </tr>235 ))}236 </tbody>237 </table>238 </div>239 <p>240 Raw source dumps are immutable and never edited in place; all transformations run241 through a pipeline that records manifests (hashes and row counts) for every derived242 artifact.243 </p>244 </Section>245246 <Section id="rating" title="4. Task rating — the multi-model panel">247 <p>248 Each task statement is rated on six dimensions (the five composite dimensions plus249 augmentation) on an integer 1–5 scale by{" "}250 <strong className="text-[var(--ink)]">at least two independent frontier language251 models</strong> using an identical, versioned rubric prompt. Ratings are requested with252 schema-constrained JSON output; each rating must include a written rationale grounded in253 the task statement.254 </p>255 <p>256 For every task × dimension, the panel produces a rating band:{" "}257 <code>low</code> = the panel minimum, <code>mid</code> = the panel mean,{" "}258 <code>high</code> = the panel maximum. Bands — not single numbers — flow into all259 downstream computation, which is how rater disagreement becomes a visible confidence260 interval instead of hidden noise.261 </p>262 <p>263 <strong className="text-[var(--ink)]">Audit trail.</strong> Every rating stores the264 model identifier, prompt version, raw API response, parsed score and rationale. On any265 occupation page, expanding a task shows every model's rating and rationale — nothing is266 asserted that cannot be inspected.267 </p>268 <p>269 <strong className="text-[var(--ink)]">Human validation.</strong> A sample of ratings is270 reviewed by humans; disagreements above one point on the 5-point scale route the task to271 an expert review queue whose overrides replace the model band and are flagged in the272 data. Prompt changes bump the prompt version and invalidate cached ratings.273 </p>274 </Section>275276 <Section id="dimensions" title="5. The five dimensions and their weights">277 <div className="overflow-x-auto card">278 <table className="w-full text-left text-sm">279 <thead className="border-b border-[var(--grid)] text-xs uppercase tracking-wide text-[var(--muted)]">280 <tr>281 <th className="px-4 py-3 font-medium">Dimension</th>282 <th className="px-4 py-3 font-medium">Weight</th>283 <th className="px-4 py-3 font-medium">Orientation</th>284 </tr>285 </thead>286 <tbody className="tabular-nums">287 {DIMENSIONS.map((key) => (288 <tr key={key} className="border-b border-[var(--grid)] last:border-b-0">289 <td className="px-4 py-3 font-medium text-[var(--ink)]">290 {DIMENSION_DETAILS.find((d) => d.key === key)?.name ?? key}291 </td>292 <td className="px-4 py-3">{(WEIGHTS[key] * 100).toFixed(0)}%</td>293 <td className="px-4 py-3">294 {INVERTED_DIMENSIONS.has(key)295 ? "inverted — higher rating lowers substitution"296 : "direct"}297 </td>298 </tr>299 ))}300 </tbody>301 </table>302 </div>303 <div className="space-y-5">304 {DIMENSION_DETAILS.map((dim) => (305 <div key={dim.key}>306 <h3 className="font-semibold text-[var(--ink)]">307 {dim.name}{" "}308 <span className="text-sm font-normal text-[var(--muted)]">309 · weight {(WEIGHTS[dim.key] * 100).toFixed(0)}%310 </span>311 </h3>312 <p className="mt-1">{dim.question}</p>313 <p className="mt-1 text-sm text-[var(--muted)]">{dim.anchors}</p>314 </div>315 ))}316 </div>317 <p>318 Weights are defined once, in a versioned source file, and served live at{" "}319 <Link href="/api/v1/methodology" className="underline">320 /api/v1/methodology321 </Link>{" "}322 — any change is a new index version with a changelog entry and regenerated sensitivity323 analyses.324 </p>325 </Section>326327 <Section id="formulas" title="6. Formulas">328 <p>329 A rating <em>r</em> ∈ [1, 5] normalizes to substitution pressure <em>p</em> ∈ [0, 1]:330 </p>331 <pre className="overflow-x-auto card p-4 text-sm text-[var(--ink)]">332 {`p = (r − 1) / 4 direct dimensions333p = 1 − (r − 1) / 4 inverted dimensions (barriers)334335substitution_task = 100 · Σ_d w_d · p_d over all five dimensions336exposure_task = 100 · (w_auto·p_auto + w_feas·p_feas) / (w_auto + w_feas)337augmentation_task = 100 · p_augmentation`}338 </pre>339 <p>340 The exposure sub-score uses only {EXPOSURE_DIMENSIONS.join(" and ")}, renormalized. The341 scoring engine is a pure, deterministic library with no network, clock or randomness —342 identical inputs always produce identical scores, which is what makes runs auditable.343 Its behavior is pinned by property-based tests and by a published worked example that344 the test suite reproduces to three decimals.345 </p>346 </Section>347348 <Section id="aggregation" title="7. From tasks to occupations">349 <p>350 Occupation scores are the importance-weighted mean of task scores, using O*NET task351 importance ratings normalized within each occupation. Tasks without an importance rating352 receive the occupation's mean importance. The same aggregation applies to the low, mid353 and high bounds.354 </p>355 <p>356 We additionally report the <strong className="text-[var(--ink)]">highly exposed task357 share</strong>: the fraction of an occupation's tasks with a substitution score of{" "}358 {HIGH_EXPOSURE_THRESHOLD} or more. "X% of tasks in this occupation are highly exposed"359 is the preferred headline reading — more honest than a single composite.360 </p>361 </Section>362363 <Section id="uncertainty" title="8. Confidence intervals">364 <p>365 The low and high bounds are worst/best-case envelopes over the rater panel: the lower366 bound takes each dimension's pressure-minimizing rating bound (for the inverted barriers367 dimension, that is the <em>high</em> rating), the upper bound symmetrically. By368 construction low ≤ score ≤ high always holds. A wide interval means the models disagreed369 — treat that score as an open question, not a verdict. Occupations with the widest370 intervals are exactly where human expert review is prioritized.371 </p>372 </Section>373374 <Section id="versioning" title="9. Versioning and immutable runs">375 <p>376 The index version ({INDEX_VERSION}) follows semantic versioning: formula or weight377 changes are major; data-source refreshes are minor; recomputations with refreshed378 adoption inputs are patches. Every computation writes a run record with the index379 version, prompt version and rater models. Runs are immutable — recomputations create new380 runs and old runs remain queryable, so any historically published score can be381 reproduced and checked forever. Every API response carries the index version it was382 computed under.383 </p>384 </Section>385386 <Section id="validation" title="10. Validation and sensitivity">387 <p>Published alongside each major or minor release:</p>388 <ul className="list-inside list-disc space-y-2">389 <li>390 <strong className="text-[var(--ink)]">Convergent validity</strong> — rank correlation391 against independent published measures (Felten AIOE, "GPTs are GPTs" task scores, ILO392 exposure gradients).393 </li>394 <li>395 <strong className="text-[var(--ink)]">Rater stability</strong> — the distribution of396 cross-model agreement; the widest-band occupations are flagged in the product.397 </li>398 <li>399 <strong className="text-[var(--ink)]">Outcome tracking</strong> — correlation against400 realized labor-market indicators (entry-level employment in exposed occupations,401 measured usage data). Exposure indices individually explain little of realized402 unemployment risk, so we report outcome tracking honestly rather than claiming403 prediction.404 </li>405 <li>406 <strong className="text-[var(--ink)]">Weight sensitivity</strong> — rank stability of407 the composite under ±25% perturbation of each weight.408 </li>409 </ul>410 </Section>411412 <Section id="limitations" title="11. Known limitations">413 <ul className="list-inside list-disc space-y-2">414 <li>415 LLM raters co-evolve with the technology they measure; multi-model panels bound this416 "ruler problem" but do not eliminate it.417 </li>418 <li>419 Sector-level adoption evidence enters through rubric anchors rather than per-sector420 statistical joins in the current version.421 </li>422 <li>423 Scores describe tasks as currently constituted; occupations reorganize, and task mixes424 shift precisely when exposure is high.425 </li>426 <li>427 Wages shown are U.S. national medians; cross-country generalization awaits the428 ESCO/ROME release.429 </li>430 <li>431 This index measures pressure, not destiny. It cannot tell an individual whether their432 job is safe; it can tell them which of their tasks are changing and how confident the433 evidence is.434 </li>435 </ul>436 </Section>437438 <Section id="citation" title="12. Citation, license and contact">439 <p>440 Cite as: <em>AI Risk Index, version {INDEX_VERSION}, airiskindex.io, Simon-Pierre441 Boucher (2026)</em>. Scores and derived data are published under{" "}442 <strong className="text-[var(--ink)]">CC BY 4.0</strong> — reuse freely with443 attribution and the index version. Occupation and task data incorporate the O*NET444 database (U.S. Department of Labor, CC BY 4.0); wage data from BLS OEWS.445 </p>446 <p>447 Methodology questions, corrections, expert-panel participation, data licensing or448 anything else:{" "}449 <a href="mailto:contact@spboucher.ai" className="underline">450 contact@spboucher.ai451 </a>{" "}452 — Simon-Pierre Boucher.453 </p>454 </Section>455 </main>456 );457}458