SPB Git forge

spb/ai-atlas

Public
41commits 1branches 0releases
4.6 MBsize
maindefault branch
12 days agolast push
HTML 77.2% TypeScript 10.5% Python 9.6% JavaScript 2.5%
17.4 KB · 388 lines tsx
Raw Blame History
1import type { Metadata } from 'next';2import Link from 'next/link';3import { SectionNav } from '@/components/layout/terminal';4import { BreadcrumbLd } from '@/components/meta/breadcrumb-ld';5import { Chip, Estimated, TierBadge } from '@/components/ui/badges';6import { DataTable, Td, Th } from '@/components/ui/data-table';7import { Container, Note, PageHeader, Section } from '@/components/ui/section';8import { Unavailable } from '@/components/ui/unavailable';9import { apiD3, safe } from '@/lib/api';10import { fmtAgo, fmtInt, humanize } from '@/lib/format';11import { eventLabel, routes, SITE_NAME, TIER_LABELS } from '@/lib/site';12import type { MethodologyD3 } from '@/lib/types';1314export const metadata: Metadata = { title: 'Methodology — provenance, tiers, openness, trust, comparability, counters, events, anomalies, estimates', description: 'How AI Atlas records facts: source tiers, confidence, temporal claims and conflicts, openness definitions, benchmark trust levels and comparability rules, counter definitions, event semantics (occurred / observed / recorded), anomaly checks, hardware-fit assumptions and frontier composition.', alternates: { canonical: '/methodology' } };15export const revalidate = 3600;1617/** The API may return dicts or lists for these vocabularies; normalise to rows. */18function rows(v: unknown, keyName: string): { key: string; label?: string; description?: string; extra?: Record<string, unknown> }[] {19  if (!v) return [];20  if (Array.isArray(v)) return v.map((x) => (typeof x === 'string' ? { key: x } : { key: String((x as Record<string, unknown>)[keyName] ?? (x as Record<string, unknown>).key ?? (x as Record<string, unknown>).name ?? ''), label: (x as Record<string, unknown>).label as string | undefined, description: ((x as Record<string, unknown>).description ?? (x as Record<string, unknown>).text) as string | undefined, extra: x as Record<string, unknown> }));21  if (typeof v === 'object') return Object.entries(v as Record<string, unknown>).map(([k, d]) => (typeof d === 'string' ? { key: k, description: d } : { key: k, ...(d as Record<string, unknown>), extra: d as Record<string, unknown> }));22  return [];23}24function Defs({ obj, mono = true }: { obj: Record<string, unknown> | undefined | null; mono?: boolean }) {25  const entries = Object.entries(obj ?? {}).filter(([, v]) => typeof v === 'string');26  if (!entries.length) return <Unavailable what="Definitions" compact />;27  return (28    <dl className="kv max-w-4xl">29      {entries.map(([k, v]) => (30        <div key={k}>31          <dt className={mono ? 'mono' : undefined}>{k}</dt>32          <dd className="text-ink-2">{String(v)}</dd>33        </div>34      ))}35    </dl>36  );37}38function Keys({ items }: { items: unknown }) {39  if (!Array.isArray(items) || !items.length) return <span className="text-ink-3">—</span>;40  return (41    <span className="flex flex-wrap gap-1">42      {items.map((k) => (43        <Chip key={String(k)} className="mono">44          {String(k)}45        </Chip>46      ))}47    </span>48  );49}5051const NAV = [52  { id: 'principles', label: 'Principles' },53  { id: 'tiers', label: 'Tiers' },54  { id: 'confidence', label: 'Confidence' },55  { id: 'openness', label: 'Openness' },56  { id: 'trust', label: 'Trust levels' },57  { id: 'comparability', label: 'Comparability' },58  { id: 'counters', label: 'Counters' },59  { id: 'events', label: 'Events' },60  { id: 'anomalies', label: 'Anomalies' },61  { id: 'estimates', label: 'Hardware fit' },62  { id: 'frontier', label: 'Frontier' },63  { id: 'quality', label: 'Quality' },64  { id: 'extractors', label: 'Extraction' },65];6667export default async function MethodologyPage() {68  const m: MethodologyD3 | null = await safe(apiD3.methodology());69  const tiers = rows(m?.tiers, 'tier');70  const conf = rows(m?.confidence_levels, 'key');71  const events = rows(m?.event_types, 'event_type');72  const extractors = rows(m?.extractors, 'key');73  const comp = (m?.comparability ?? {}) as Record<string, unknown>;74  const hf = (m?.hardware_fit ?? {}) as { assumptions?: string[]; bytes_per_param?: Record<string, number>; reserved_gb?: number };75  return (76    <Container>77      <BreadcrumbLd items={[{ name: SITE_NAME, href: '/' }, { name: 'Methodology', href: '/methodology' }]} />78      <PageHeader eyebrow="Methodology 2.0" title="How AI Atlas records facts" lede="The dataset is the product. These are the rules every connector, extractor and page follows — and the vocabularies the API exposes. Everything on this page is read from GET /methodology; nothing is hardcoded." aside={m?.quality_version ? <p className="mono text-xs text-ink-3">quality v{m.quality_version}</p> : undefined} />79      <SectionNav items={NAV} />80      {!m && <Unavailable what="Methodology" className="my-8" />}8182      <Section id="principles" eyebrow="Principles" title="Non-negotiables" hairline={false}>83        {m?.principles?.length ? (84          <ol className="max-w-3xl list-decimal space-y-1.5 pl-5 text-[15px] leading-relaxed text-ink-2">85            {m.principles.map((p) => (86              <li key={p}>{p}</li>87            ))}88          </ol>89        ) : (90          <div className="prose-atlas max-w-3xl text-[15px] leading-relaxed text-ink-2">91            <p>AI Atlas is built from first-party connectors that read public documents directly. Every document is snapshotted and archived; every fact points back to a snapshot. Facts are temporal claims — a property, a value, a source, a tier, a confidence, an extractor and a validity interval. Missing means missing.</p>92          </div>93        )}94      </Section>9596      <Section id="tiers" eyebrow="Source tiers" title="Primary sources first">97        {m && tiers.length ? (98          <DataTable caption="Source tiers">99            <thead>100              <tr>101                <Th>Tier</Th>102                <Th>Meaning</Th>103                <Th>Description</Th>104              </tr>105            </thead>106            <tbody>107              {tiers.map((t, i) => (108                <tr key={`${t.key}-${i}`}>109                  <Td primary>110                    <TierBadge tier={Number(t.key)} />111                  </Td>112                  <Td label="Meaning" className="text-ink">{t.label ?? TIER_LABELS[Number(t.key)] ?? humanize(t.key)}</Td>113                  <Td label="Description" wide className="text-ink-2">{t.description ?? '—'}</Td>114                </tr>115              ))}116            </tbody>117          </DataTable>118        ) : (119          <Unavailable what="Tier vocabulary" compact />120        )}121        <p className="mt-3 max-w-3xl text-sm text-ink-2">A higher tier can supersede a lower one; the reverse produces a flagged conflict. Both claims are kept.</p>122      </Section>123124      <Section id="confidence" eyebrow="Confidence" title="Confidence levels">125        {m && conf.length ? (126          <dl className="kv max-w-3xl">127            {conf.map((c, i) => (128              <div key={`${c.key}-${i}`}>129                <dt className="mono">{c.key}</dt>130                <dd className="text-ink-2">{c.description ?? c.label ?? '—'}</dd>131              </div>132            ))}133          </dl>134        ) : (135          <Unavailable what="Confidence vocabulary" compact />136        )}137        {m?.status_vocabulary?.length ? (138          <p className="mt-3 text-sm text-ink-2">139            Status vocabulary: <Keys items={m.status_vocabulary} />140          </p>141        ) : null}142      </Section>143144      <Section id="openness" eyebrow="Openness" title="Openness is derived from measurable dimensions" lede={m?.openness?.note}>145        {m?.openness ? (146          <>147            <DataTable caption="Openness categories" compact>148              <thead>149                <tr>150                  <Th>Category</Th>151                  <Th>Label</Th>152                  <Th>Definition</Th>153                </tr>154              </thead>155              <tbody>156                {m.openness.categories.map((c) => (157                  <tr key={c}>158                    <Td primary className="mono text-xs">{c}</Td>159                    <Td label="Label" className="text-ink">{m.openness?.labels?.[c] ?? humanize(c)}</Td>160                    <Td label="Definition" wide className="text-ink-2">{m.openness?.definitions?.[c] ?? '—'}</Td>161                  </tr>162                ))}163              </tbody>164            </DataTable>165            <p className="mt-3 text-sm text-ink-2">166              Dimensions: <Keys items={m.openness.dimensions} />167            </p>168            {m.licence_categories?.length ? (169              <p className="mt-2 text-sm text-ink-2">170                Licence categories: <Keys items={m.licence_categories} />171              </p>172            ) : null}173          </>174        ) : (175          <Unavailable what="Openness definitions" compact />176        )}177      </Section>178179      <Section id="trust" eyebrow="Benchmarks" title="Trust levels of a result">180        {m?.trust_levels?.length ? (181          <dl className="kv max-w-3xl">182            {(m.trust_levels as { key: string; label: string; description?: string }[]).map((t) => (183              <div key={t.key}>184                <dt className="mono">{t.key}</dt>185                <dd className="text-ink-2">{t.label}{t.description ? ` — ${t.description}` : ''}</dd>186              </div>187            ))}188          </dl>189        ) : (190          <Unavailable what="Trust levels" compact />191        )}192      </Section>193194      <Section id="comparability" eyebrow="Benchmarks" title="Results are never compared blindly" lede={typeof comp.group === 'string' ? comp.group : undefined}>195        {Object.keys(comp).length ? (196          <>197            <dl className="kv max-w-4xl">198              {(['comparable', 'partially-comparable', 'not-comparable'] as const).filter((k) => typeof comp[k] === 'string').map((k) => (199                <div key={k}>200                  <dt className="mono">{k}</dt>201                  <dd className="text-ink-2">{String(comp[k])}</dd>202                </div>203              ))}204              {typeof comp.leaderboard === 'string' && (205                <div>206                  <dt>Leaderboards</dt>207                  <dd className="text-ink-2">{comp.leaderboard}</dd>208                </div>209              )}210            </dl>211            <div className="mt-4 grid gap-4 md:grid-cols-3">212              <div>213                <p className="eyebrow mb-1.5">Task-defining keys</p>214                <Keys items={comp.task_keys} />215              </div>216              <div>217                <p className="eyebrow mb-1.5">Condition keys</p>218                <Keys items={comp.condition_keys} />219              </div>220              <div>221                <p className="eyebrow mb-1.5">Ignored keys</p>222                <Keys items={comp.ignored_keys} />223              </div>224            </div>225          </>226        ) : (227          <Unavailable what="Comparability rules" compact />228        )}229      </Section>230231      <Section id="counters" eyebrow="Counters" title="How every number is counted">232        <Defs obj={m?.counters} />233      </Section>234235      <Section id="events" eyebrow="History" title="Change events: occurred, observed, recorded">236        <Defs obj={m?.event_semantics} />237        {m && events.length ? (238          <DataTable caption="Event types" className="mt-5" compact>239            <thead>240              <tr>241                <Th>Event type</Th>242                <Th>Label</Th>243                <Th>Category</Th>244                <Th num>Importance</Th>245                <Th num>Recorded</Th>246                <Th>Last seen</Th>247              </tr>248            </thead>249            <tbody>250              {events.map((e, i) => (251                <tr key={`${e.key}-${String(e.extra?.category ?? '')}-${i}`}>252                  <Td primary className="mono text-xs">{e.key}</Td>253                  <Td label="Label" className="text-ink-2">{e.label ?? e.description ?? eventLabel(e.key)}</Td>254                  <Td label="Category" className="text-ink-2">{String(e.extra?.category ?? '—')}</Td>255                  <Td num label="Importance" className="tnum text-ink-2">{e.extra?.importance !== undefined ? String(e.extra.importance) : '—'}</Td>256                  <Td num label="Recorded" className="tnum text-ink-2">{e.extra?.count !== undefined ? fmtInt(e.extra.count) : '—'}</Td>257                  <Td label="Last seen" className="text-ink-2">{typeof e.extra?.last_seen_at === 'string' ? fmtAgo(e.extra.last_seen_at) : '—'}</Td>258                </tr>259              ))}260            </tbody>261          </DataTable>262        ) : (263          <Unavailable what="Event vocabulary" compact className="mt-4" />264        )}265      </Section>266267      <Section id="anomalies" eyebrow="Data health" title="Anomaly checks" lede="Impossible or suspicious values are flagged, never deleted; each flag points at a review action.">268        {m?.anomaly_checks?.length ? (269          <DataTable caption="Anomaly checks" compact>270            <thead>271              <tr>272                <Th>Check</Th>273                <Th>Severity</Th>274                <Th>Description</Th>275              </tr>276            </thead>277            <tbody>278              {m.anomaly_checks.map((c) => (279                <tr key={c.check}>280                  <Td primary className="mono text-xs">{c.check}</Td>281                  <Td label="Severity">282                    <span className={c.severity === 'critical' ? 'text-danger' : c.severity === 'warning' ? 'text-warning' : 'text-ink-2'}>{c.severity}</span>283                  </Td>284                  <Td label="Description" wide className="text-ink-2">{c.description}</Td>285                </tr>286              ))}287            </tbody>288          </DataTable>289        ) : (290          <Unavailable what="Anomaly checks" compact />291        )}292      </Section>293294      <Section id="estimates" eyebrow="Estimates" title={<>Hardware fit is an estimate <Estimated className="ml-2 align-middle" /></>}>295        {hf.assumptions?.length ? (296          <ul className="max-w-3xl list-disc space-y-1 pl-5 text-sm leading-relaxed text-ink-2">297            {hf.assumptions.map((a) => (298              <li key={a}>{a}</li>299            ))}300          </ul>301        ) : (302          <Unavailable what="Hardware-fit assumptions" compact />303        )}304        {hf.bytes_per_param && (305          <p className="mt-3 text-sm text-ink-2">306            Bytes per parameter:{' '}307            {Object.entries(hf.bytes_per_param).map(([k, v], i) => (308              <span key={k} className="tnum">309                {i > 0 && ' · '}310                <span className="mono">{k}</span> {v}311              </span>312            ))}313            {hf.reserved_gb !== undefined && <> · reserved {hf.reserved_gb} GB</>}314          </p>315        )}316      </Section>317318      <Section id="frontier" eyebrow="Frontier" title="Frontier composition">319        {typeof m?.frontier === 'string' ? <p className="max-w-3xl text-sm leading-relaxed text-ink-2">{m.frontier}</p> : m?.frontier ? <Defs obj={m.frontier as Record<string, unknown>} mono={false} /> : <Unavailable what="Frontier definition" compact />}320        {m?.find_a_model && (321          <>322            <p className="eyebrow mb-1.5 mt-5">Find-a-model rules</p>323            <Defs obj={m.find_a_model} />324          </>325        )}326      </Section>327328      <Section id="quality" eyebrow="Data quality" title="The quality score measures our knowledge, not the entity">329        {m && m.metrics?.length > 0 ? (330          <DataTable caption="Metric definitions">331            <thead>332              <tr>333                <Th>Metric</Th>334                <Th>Definition</Th>335                <Th>Version</Th>336              </tr>337            </thead>338            <tbody>339              {m.metrics.map((x, i) => (340                <tr key={String(x.key ?? x.name ?? i)}>341                  <Td primary className="mono text-xs">{String(x.key ?? x.name ?? '—')}</Td>342                  <Td label="Definition" wide className="text-ink-2">{String(x.description ?? x.formula ?? x.label ?? '—')}{x.unit ? <span className="text-ink-3"> · {String(x.unit)}</span> : null}</Td>343                  <Td label="Version" className="mono text-xs text-ink-3">{x.version !== undefined ? String(x.version) : '—'}</Td>344                </tr>345              ))}346            </tbody>347          </DataTable>348        ) : (349          <Unavailable what="Metric definitions" compact />350        )}351        {m?.expected_fields && (352          <>353            <p className="eyebrow mb-1.5 mt-5">Expected fields per type (completeness)</p>354            <dl className="kv max-w-4xl">355              {Object.entries(m.expected_fields).map(([t, fields]) => (356                <div key={t}>357                  <dt className="mono">{t}</dt>358                  <dd>359                    <Keys items={fields} />360                  </dd>361                </div>362              ))}363            </dl>364          </>365        )}366      </Section>367368      <Section id="extractors" eyebrow="Extraction" title="Deterministic before LLM">369        {m && extractors.length > 0 ? (370          <dl className="kv max-w-3xl">371            {extractors.map((x, i) => (372              <div key={`${x.key}-${i}`}>373                <dt className="mono">{x.key}</dt>374                <dd className="text-ink-2">{x.description ?? x.label ?? '—'}</dd>375              </div>376            ))}377          </dl>378        ) : (379          <Unavailable what="Extractor vocabulary" compact />380        )}381        <Note className="mt-4">382          Connectors honour robots.txt, use per-domain rate limits and conditional requests, identify as <Link href={routes.bot()} className="link mono">AIAtlasBot</Link>, never bypass access controls and never collect private data. Sources and connector health: <Link href={routes.sources()} className="link">/sources</Link>.383        </Note>384      </Section>385    </Container>386  );387}388