import type { Metadata } from 'next'; import { ConfidenceBadge, EventTypeBadge, SignificanceBadge } from '@/components/ui/badges'; import { Container, Note, PageHeader, Section, Unavailable } from '@/components/ui/section'; import { api, safe } from '@/lib/api'; import { METRIC_LABELS } from '@/lib/site'; export const metadata: Metadata = { title: 'Methodology', description: 'How Company Atlas computes Activity Score, Hiring Momentum, Product Velocity, AI Adoption, the Corporate Change Index and significance bands — with formula versions and inputs.' }; export const revalidate = 3600; export default async function MethodologyPage() { const m = await safe(api.methodology()); const bands = Array.isArray(m?.significance_bands) ? m.significance_bands : m?.significance_bands ? Object.entries(m.significance_bands).map(([label, [min, max]]) => ({ label, min, max })) : []; const labels: ReadonlyArray = m?.confidence_labels ? Array.isArray(m.confidence_labels) ? m.confidence_labels.map((l) => (typeof l === 'string' ? ([l, ''] as const) : ([l.label, l.min_confidence != null ? `confidence ≥ ${Math.round(l.min_confidence * 100)} %` : ''] as const))) : Object.entries(m.confidence_labels).map(([k, v]) => [k, String(v)] as const) : []; return ( {!m ? ( ) : ( <>
{m.metrics.map((x) => (

{METRIC_LABELS[x.metric] ?? x.metric}

{x.metric} · {x.formula_version}

{x.description}

{x.inputs.length > 0 && (

{x.inputs.map((i) => ( {i} ))}

)}
))}
{bands.map((b) => (

{b.min.toFixed(2)} – {b.max.toFixed(2)}

))}
Inputs: percentage of text changed, semantic similarity, page importance, affected structured entities (jobs, plans, people, locations), novelty against the sensor’s history and cross-source confirmation. Only changes above the meaningful band produce events; lower bands are archived, never discarded.
    {labels.map(([l, d]) => (
  • {d}
  • ))}

{m.event_types.map((t) => ( ))}

Subtypes include product launch / no longer listed / renamed, price increase / decrease / new tier, job count increase / decrease, new executive / executive no longer listed, new office / office no longer listed / country expansion, new partnership, acquisition, divestiture, API launch, documentation change, terms change and brand repositioning.

As the network grows, raw counts of observations and events rise regardless of what companies do. The Global Corporate Activity Index and industry/country series are normalised by the number of active sensors, the company population, crawl frequency and industry/country coverage in each window, so a rising index means more change per monitored surface — not more surfaces. Baselines are computed per sensor and per company (changes per week, job counts, announcement frequency, volatility) and drive the anomaly score.

)}
); }