An official website of the Disclosure Foundation
Datasets

v1 · Previous stable standard

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 observableAssessments and origin feed compellingness instead.

On this page

Usage
The result
What counts as present
Derived from the schema, not hardcoded
What completeness is not