Overview
@disclosureos/schema — the portable contract that binds records and package-owned slots into one validated observation
@disclosureos/schema is not another part of the standard. It's the contract: the package that takes the records core and the registered slots and makes them one thing — in TypeScript, in JSON Schema, and at runtime.
npm install @disclosureos/schemaInstall it whenever a record can carry more than the core lexicon. In practice: always, except in tools that only ever touch core records.
The three things it does
| Capability | Export | Solves |
|---|---|---|
| Non-stripping validation | parseEnrichedObservation | The strip hazard — validate core + slots in one call, nothing dropped |
| Runtime slot registry | ExtensionRegistry, defaultRegistry | TS module augmentation is compile-time only; the registry mirrors it at runtime |
| Composed JSON Schema | composeObservationSchema | One portable artifact for Python, Rust, validators, and docs |
One import, full contract
Importing the package does three things at once:
import { parseEnrichedObservation, type EnrichedObservation } from '@disclosureos/schema';- Types — both satellite packages are imported, so
observableAssessmentsandoriginare typed onObservation.EnrichedObservationnames that complete shape. - Runtime — both first-party slots are registered on
defaultRegistry. - Validation —
parseEnrichedObservationis ready to validate the whole enriched record.
const result = parseEnrichedObservation(record);
if (result.success) {
// result.data — the SAME object you passed in, slots intact
} else {
// result.issues — [{ path: 'origin[0].confidence', message: '...' }, ...]
}Why a contract package exists
The records core schema can't know about the slots — records can't depend on its own satellites. That leaves a gap with two failure modes:
- The strip hazard:
ObservationSchema.parse()silently drops slot data. - The portability gap: TS module augmentation is invisible to JSON Schema and non-TS languages.
@disclosureos/schema closes both at the integration layer, by delegation: the core is validated by records' own validator, each slot by its owner package's validator, and the JSON Schemas are merged as plain data. No layer's authority is duplicated; the contract just composes them.
Design properties
- Registry-driven. Validation and schema composition both walk the registry. A newly registered slot is validated and composed with no changes to either code path.
- Closed root, open extension area. Unknown top-level keys are rejected (typo protection); arbitrary third-party data still flows through the
extensionsbag. - Reference-equal on success.
parseEnrichedObservationreturns your object, not a reconstruction — nothing is stripped because nothing is rebuilt. - Versioned artifact. The composed schema is enveloped with
$idandx-schema-version(ENRICHED_OBSERVATION_SCHEMA_VERSION), with drift tests guarding the committed artifact.