04 Schema

One schema, every language

The wire is validated by a single JSON Schema (Draft 2020-12): contextgraph-envelope.schema.json. The root validates one envelope; every payload shape is also exposed under $defs for granular validation.

There is no separate IDL — the contextgraph-types Rust structs serialized by serde are the protocol, and the schema mirrors them exactly. It validates with ajv, Python jsonschema, Rust jsonschema, Go gojsonschema — any Draft 2020-12 validator. Find it in the repository under schema/.

ContextFrame

Table 2 — ContextFrame fields. = required (what the reference serializer always emits).
FieldTypeNotes
idstringNon-empty, provider-scoped.
kindFrameKindsnippet | symbol | fact | doc | memory | episode | graph
titlestringNon-empty.
scorenumberRelevance in [0, 1].
token_costu32Canonical: ceil(utf8_bytes(content)/4).
contentstring?Untrusted data. Governed per representation — omitted entirely for reference frames.
representationenum?full | compact | reference; absent ⇒ full.
content_digeststring?sha256: + 64 hex. Omitting it makes the frame unverifiable.
content_refobject?{ provider_id, uri, expires_at? } — opaque resolver handle.
canonical_content_hashstring?Hash of the full canonical source.
content_fidelityenum?exact | normalized | summarized | omitted
transformobject?{ method, implementation, version } for compact renderings.
canonical_token_costu32?Cost of the canonical source; tokenizer_ref names the tokenizer (e.g. openai:o200k_base).
valid_from / valid_totimestamp?Bi-temporal validity bounds.
recorded_attimestamp?When the frame was captured.
provenanceProvenance[]Omitted when empty.
citation_labelstring?Non-empty when present.
embeddingobject?{ fingerprint, vector? }
relationsRelation[]The graph: labelled edges. Omitted when empty.
A real conforming frame — from the golden fixturesjson
{
  "id": "frame:minimal",
  "kind": "fact",
  "title": "Minimal conforming frame",
  "content": "Default arrays are omitted on the wire.",
  "score": 1.0,
  "token_cost": 10,
  "citation_label": "minimal fixture"
}

ContextQuery

Table 3 — ContextQuery fields.
FieldTypeNotes
goalstringThe driving task — verbatim intent, not keywords.
kindsFrameKind[]Empty means “your best frames of any kind.”
anchorsstring[]Focal URIs — open files, mentioned symbols.
max_framesu32Hard cap on returned frames.
max_tokensu32A hard contract, not a hint.
query_textstring?Optional keyword rendering of the goal.
embeddingnumber[]?Only sendable when host and provider fingerprints match exactly (E1).
as_oftimestamp?Pin retrieval to an instant.
representation_preferencesenum[]?Ordered; absent ⇒ [full].

Provenance and Relation

A Provenance record requires a type (the Rust field kind serializes to type on the wire) and may carry uri, range, digest (pattern ^sha256:[0-9a-f]{64}$), method, and by. A Relation requires rel and target_uri, with an optional display_name.

Structural rules the schema enforces: required fields, score ∈ [0,1], non-empty title/citation_label/id, the frame-kind enum, the contextgraph/MAJOR.MINOR(-draft)? version pattern, u32 ranges, and the per-representation content/content_ref/transform conditionals.