Completeness
Field coverage of the records schema — what's documented, what's missing
Completeness answers: is this record well-documented? It measures how fully an observation populates the records schema — nothing more. It says nothing about whether the case is interesting; that's compellingness.
Usage
import { getCompleteness } from '@disclosureos/scoring';
const result = getCompleteness(observation);The result
interface CompletenessResult {
total: number; // leaf field paths defined by the records schema
present: number; // how many carry a value
percentage: number; // present / total, 0–100 integer
missing: string[]; // exactly which paths are absent or empty
requiredTotal: number; // schema-required leaf paths
requiredPresent: number;
requiredPercentage: number; // 0–100 integer
}Two percentages, because they answer different questions:
requiredPercentage— is this a structurally complete record? (100 for anything a factory produced.)percentage— how much of the full lexicon does it use? Most real records sit well under 50, and that's fine.
The missing array is the actionable part — it's a work list for researchers improving a record:
result.missing;
// ['movement.speedKmh', 'witnesses.descriptions', 'environment.weather', ...]What counts as present
A field is present when it carries a non-empty value: non-empty strings, non-empty arrays, objects with at least one key, and any number or boolean. null, undefined, '', [], and {} count as missing.
Derived from the schema, not hardcoded
The field inventory is derived from the records JSON Schema at runtime via deriveFieldPaths() — when the lexicon grows, completeness automatically accounts for the new fields. You can inspect or override the inventory:
import { deriveFieldPaths, getCompleteness } from '@disclosureos/scoring';
const paths = deriveFieldPaths();
// [{ path: 'temporal.date', required: true }, { path: 'movement.speedKmh', required: false }, ...]
// Score against a custom subset — e.g. your project's "minimum publishable record"
const result = getCompleteness(observation, {
paths: paths.filter((p) => myMinimumSet.has(p.path)),
});What completeness is not
- Not a quality score. A complete record of a streetlight sighting is still a streetlight.
- Not validation. An invalid record can be "complete" — validate first (Validating at Boundaries).
- Not about the slots. Completeness measures the core record. Claims in
observableAssessmentsandoriginfeed compellingness instead.