JSON-CORE-LD v0.1.0
The JSON encoding binding for the CORE-LD foundational profile — deterministic, lossless serialization of CORE-LD abstract representations as JSON-LD documents.Status: Draft Encodes: CORE-LD v0.1.0 (foundational profile) Constitutional dependencies: URS v0.1.0 → CORE-LD v0.1.0 Spec family: Encoding Binding (CCA Framework §3; CORE-LD §6.2 — Adding an encoding binding) Encoding rule: CORE-LD + JSON Canonical @context: https://specs.initialcore.net/ns/core-ld.jsonld Media types: application/json (canonical), application/ld+json (linked-data view)
1. Preamble
JSON-CORE-LD is the encoding binding that serializes the CORE-LD abstract representation as deterministic JSON. Per CORE-LD §1.1, it sits at the syntax-specific layer of the dimensional architecture:
Reality → USC → URS → CORE-LD → [functional profiles] → [encoding bindings] → CodeLabs → CoreFab → studio
Foundational Role-specific Syntax-specific
What JSON-CORE-LD is:
- A deterministic, lossless mapping between the CORE-LD abstract representation and JSON bytes
- The reference encoding binding for the DAG-*-LD family — the canonical form against which other bindings (CBOR-CORE-LD, etc.) are measured
- The encoding used by the URS Conformance Suite (`urs_conformance.py`) and all profile conformance extensions
What JSON-CORE-LD is not:
- Not a functional profile — it adds no semantics; it preserves CORE-LD semantics exactly
- Not an addressing mode — content addressing (DAG) composes with it via URS Canonicalization, it does not define it
- Not a new data model — the URS/CORE-LD data model is the only authority; this spec only fixes byte representation
Composition rule (per CORE-LD §6.2):
JSON-CORE-LD = CORE-LD + JSON encoding
JSON-[PROFILE]-LD = CORE-LD + [PROFILE] + JSON encoding (multi-profile binding, §8)
A conforming JSON-CORE-LD implementation MUST preserve all 23 CORE-LD invariants (I1–I23) in the encoding, MUST define a deterministic lossless mapping between the abstract representation and JSON bytes, and MUST round-trip any valid CORE-LD representation without loss of identity (L1/L2/L3 per CORE-LD §3.1).
Relation to earlier codecs: JSON-CORE-LD v0.1.0 subsumes DAG-JSON-LD v0.1.0 (the pre-CORE-LD JSON codec draft). DAG-JSON-LD's framing and serialization rules are inherited and aligned to the CORE-LD frame (§2.1 of CORE-LD); DAG-JSON-LD remains on record as the historical draft. The framing algorithm (§4) and canonical JSON rules (§5) here are the live versions.
2. JSON Value Model
The URS representation kinds map to JSON types as follows. Every mapping is total and invertible on valid CORE-LD frames.
| CORE-LD construct | JSON representation | Notes |
|---|---|---|
| Representation (document) | Top-level JSON object | MUST carry `@context` (§3) |
| Entity | JSON object with `@id` + `@type` | One object per entity |
| Property | Key/value pair on the entity object | Name MUST be a defined term (§3.3) |
| Property value (literal) | JSON string / number / boolean / null | Per RFC 8259 |
| Property value (entity ref) | JSON string equal to target `@id` | Resolves within the document graph (I4) |
| Identifier | `@id` string, or Identifier object (§2.3 CORE-LD) | Explicit `identifier` object for scope/hash metadata |
| Link | Link object inside the `links` array | `source`, `target`, `linkType` required (I6, I7) |
| Group | Object with `groupVariant` + `members` / `entries` | Set/Sequence use `members`; Map uses `entries` |
| Provenance | `provenance` object on entity or document | Fields per CORE-LD §4.1 |
| @context | `@context` key: IRI string or array of IRIs | §3 |
JSON scalar rules (JSON-CORE-LD subset of RFC 8259):
- Strings: Unicode, UTF-8 encoded at serialization; no unpaired surrogates.
- Numbers: IEEE-754 double-precision subset, serialized in shortest round-trip form (RFC 8785 §3.2.3); integers without fraction/exponent when integral.
- Booleans: `true` / `false` only. Null: `null` — meaning absent value, not absent property.
- No `undefined`, no NaN/Infinity, no comments, no trailing commas, no BOM.
3. Term Mapping and @context
3.1 Context requirement
Every JSON-CORE-LD document MUST declare @context resolving to the CORE-LD canonical context (CORE-LD §8), either as a single IRI string: [fragments shown below are declaration-syntax illustrations only — complete conforming documents appear in §9]
{"@context": "https://specs.initialcore.net/ns/core-ld.jsonld"}
or, for multi-profile bindings, as an ordered array (§8):
{"@context": [
"https://specs.initialcore.net/ns/core-ld.jsonld",
"https://specs.initialcore.net/ns/input-ld.jsonld"
]}
3.2 Keyword usage
| JSON-LD keyword | JSON-CORE-LD rule |
|---|---|
| `@context` | Mandatory on the document; MUST NOT appear on nested entities |
| `@id` | Entity, Link, and Group identity; IRI or blank node (`_:` prefix). Duplicates prohibited across the graph (I3) |
| `@type` | Entity kind. Drawn from {Entity, Property, Identifier, Link, Group} or a registered extension (I1) |
| `@container` | Used only inside context definitions, never in data |
3.3 Defined-term rule
A property name in a JSON-CORE-LD document is valid iff it is: 1. a term defined in the active @context (core, profile, or registered extension); or 2. a compact IRI whose prefix is defined in the active @context; or 3. an absolute IRI (scheme present).
Terms from the CORE-LD context (CORE-LD §8): Entity, Property, Identifier, Link, Group, Set, Sequence, Map, kind, name, description, identifier, provenance, links, members, entries, groupVariant, source, target, linkType, isConstitutional, scope, canonicalHash, Representer, Timestamp, Authority, authorityType, RepresentationContext, PriorState, mayDelegate, delegationDepth, inherent, granted, derived, local. All expand to https://specs.initialcore.net/ns/urs#… or https://schema.org/… per the context document.
4. Framing
JSON-CORE-LD applies the CORE-LD frame (§2.1 canonical form) in 7 steps. Framing is bijective: any valid CORE-LD abstract representation frames to exactly one JSON-CORE-LD document, and any JSON-CORE-LD document unframes to exactly one abstract representation.
1. Extract root — identify the root entity (I11: exactly one entity not referenced by another). The root becomes the top-level object. 2. Assign @id — constitutional identifiers keep their did:/IRI verbatim; local identifiers use _: blank nodes; identifierless entities receive a generated blank node (document-scoped). 3. Embed properties — property name/value pairs attach directly to their owning entity object; entity-reference values are written as the target's @id string (I4). 4. Frame links — Link objects serialize into the owning entity's links array, each with source, target, linkType, and any constitutional metadata (I6, I7). 5. Frame groups — Group entities serialize with groupVariant and the variant-appropriate container: members array (Set — unordered canonical order per §5.1; Sequence — preserved order) or entries object (Map — keys sorted per §5.1). (I8, I9, I10) 6. Canonical ordering — object keys sorted per §5.1; arrays keep semantic order (Sequence members, links) or canonical order (Set members, Map entries). 7. Attach provenance — the entity's provenance block attaches to its object; document-level provenance attaches to the root when no entity carries its own (I16–I20 inheritance per CORE-LD §4.3).
5. Deterministic Serialization
5.1 Canonical JSON rules
The canonical JSON-CORE-LD byte form follows RFC 8785 (JCS) restricted to the JSON value model of §2:
1. Object keys sorted in code-point order (UTF-16 code units, per RFC 8785 §3.2.3). 2. No insignificant whitespace; {"a":1,"b":2} not { "a": 1 }. 3. Strings: shortest escaping, non-ASCII emitted as UTF-8 bytes (no \uXXXX for printable non-ASCII), / not escaped. 4. Numbers: shortest round-trip double serialization; no exponent for integral values in range. 5. Arrays preserve element order as framed. 6. UTF-8 without BOM; LF line ending irrelevant (no whitespace emitted).
5.2 Canonical hash
- L2 content hash (CORE-LD §3.1): SHA-256 over the canonical JSON of the framed document with `@context` and all `provenance` blocks removed — identifiers and properties only. Multihash-wrapped (0x12 0x20), multibase `z`-prefixed, per URS Canonicalization.
- L3 constitutional hash: SHA-256 over the full canonical JSON including provenance — same algorithm, provenance included.
- Determinism: the same abstract representation always yields identical bytes (I21), so identical L2/L3 hashes.
Implementation note: the current conformance suite's I21/I22 checks use a structural hash (sorted {id, kind} entity summaries + root) as a lightweight determinism/structural-identity proxy. The §5.2 content-level hash is the normative definition for L2/L3 claims and is not yet exercised by the suite; wiring it in is tracked as a follow-up.
6. Invariant Preservation
Every CORE-LD invariant is preserved by construction of the encoding. The conformance suite (urs_conformance.py) validates them directly against JSON-CORE-LD documents.
| Invariant group | CORE-LD §7 | JSON-CORE-LD check |
|---|---|---|
| Structural (I1–I11) | §7.1 | Parse + frame the document; run suite checks I1–I11 on the framed form |
| Identity (I12–I15) | §7.2 | Validate `canonicalHash` format, blank-node prefixes, provenance on constitutional identifiers |
| Provenance (I16–I19) | §7.3 | Validate provenance block fields, authority types, delegation flags/depth |
| Context (I20) | §7.4 | RepresentationContext present or inheritable — the base suite derives it from document-level or entity `provenance` (framing step 7); a bare `@context` array is not sufficient on its own |
| Canonicalization (I21–I23) | §7.5 | Deterministic serialization (§5.1) is self-consistent; acyclicity check on the framed graph |
No JSON encoding choice may weaken a check: e.g., I14 (local identifiers use _:) is enforced on the @id string itself, not on any JSON container.
7. Round-Trip Transformation
CORE-LD abstract representation → frame (§4) → canonical JSON (§5.1) → parse → abstract representation
Round-trip invariants (RT):
| ID | Invariant | Level |
|---|---|---|
| RT-1 | Structural identity | Unframing the framed JSON yields the same entity graph under blank-node relabeling (L1, CORE-LD §3.1) |
| RT-2 | Content identity | L2 content hash is preserved: hash(original) = hash(framed → reframed) (L2) |
| RT-3 | Constitutional identity | Full document including provenance round-trips byte-identically when re-framed from canonical form (L3) |
Documented lossy encodings (applications MUST NOT use them for constitutional claims): binary bytes → base64 strings (opaque, content-address changes); identifierless entities → generated blank nodes (labels unstable across documents); deep nesting beyond implementation limits → parse failure, never silent truncation.
8. Multi-Profile Binding
Encoding bindings compose with functional profiles. A JSON-encoded profile document (e.g., JSON-INPUT-LD) is a JSON-CORE-LD document that additionally satisfies the profile's invariants.
Binding rule (per CORE-LD §6.2, item 2):
JSON-[PROFILE]-LD encodes CORE-LD + [PROFILE]
1. @context is the ordered array [core-ld.jsonld, <profile>-ld.jsonld]. 2. All CORE-LD invariants apply unchanged (profiles only add, never relax — CORE-LD §6.1). 3. Profile invariants (I-INPUT-, I-MEM-, I-POL-, I-TRUST-) are validated by the profile conformance extensions (profile_conformance.py). 4. The canonical serialization rules (§5) are identical; profile documents hash deterministically the same way.
Binding matrix (v0.1.0 family):
| Binding | Encodes | Profile invariants added | Conformance |
|---|---|---|---|
| JSON-CORE-LD | CORE-LD | — | `urs_conformance.py` (I1–I23) |
| JSON-INPUT-LD | CORE-LD + INPUT-LD | I-INPUT-1…12 | `python3 profile_conformance.py verify <file> --profile INPUT-LD` |
| JSON-MEMORY-LD | CORE-LD + MEMORY-LD | I-MEM-1…18 | `python3 profile_conformance.py verify <file> --profile MEMORY-LD` |
| JSON-POLICY-LD | CORE-LD + POLICY-LD | I-POL-1…19 | `python3 profile_conformance.py verify <file> --profile POLICY-LD` |
| JSON-TRUST-LD | CORE-LD + TRUST-LD | I-TRUST-1…20 | `python3 profile_conformance.py verify <file> --profile TRUST-LD` |
Profiles are auto-detected from the document's @context array when --profile auto (the default) is used.
9. Examples
9.1 Minimal entity
{"@context":"https://specs.initialcore.net/ns/core-ld.jsonld","@id":"_:e1","@type":"Entity","name":"Minimal","provenance":{"Representer":"did:icore:admin","Timestamp":"2026-07-31T00:00:00Z","Authority":{"authorityType":"inherent"},"RepresentationContext":"urn:icore:context:main"}}
9.2 Constitutional entity with provenance
{"@context":"https://specs.initialcore.net/ns/core-ld.jsonld","@id":"did:icore:admin","@type":"Entity","name":"Admin","identifier":{"@type":"Identifier","@id":"did:icore:admin","scope":"constitutional","isConstitutional":true},"provenance":{"Representer":"did:icore:root","Timestamp":"2026-07-31T00:00:00Z","Authority":{"authorityType":"inherent"},"RepresentationContext":"urn:icore:context:main"}}
9.3 Link
{"@context":"https://specs.initialcore.net/ns/core-ld.jsonld","@id":"_:root","@type":"Entity","links":[{"@id":"_:l1","@type":"Link","source":"_:root","target":"_:child","linkType":"contains"}],"_:child":{"@id":"_:child","@type":"Entity","name":"child"},"provenance":{"Representer":"did:icore:admin","Timestamp":"2026-07-31T00:00:00Z","Authority":{"authorityType":"inherent"},"RepresentationContext":"urn:icore:context:main"}}
9.4 Group (Sequence)
{"@context":"https://specs.initialcore.net/ns/core-ld.jsonld","@id":"_:seq","@type":"Group","groupVariant":"Sequence","members":[{"@id":"_:m1","@type":"Entity"},{"@id":"_:m2","@type":"Entity"}],"provenance":{"Representer":"did:icore:admin","Timestamp":"2026-07-31T00:00:00Z","Authority":{"authorityType":"inherent"},"RepresentationContext":"urn:icore:context:main"}}
9.5 Group (Map)
{"@context":"https://specs.initialcore.net/ns/core-ld.jsonld","@id":"_:map","@type":"Group","groupVariant":"Map","entries":{"alpha":{"@id":"_:a","@type":"Entity"},"beta":{"@id":"_:b","@type":"Entity"}},"provenance":{"Representer":"did:icore:admin","Timestamp":"2026-07-31T00:00:00Z","Authority":{"authorityType":"inherent"},"RepresentationContext":"urn:icore:context:main"}}
10. Conformance
10.1 Implementation requirements
A conforming JSON-CORE-LD implementation MUST:
1. Parse JSON-CORE-LD documents using the CORE-LD frame (§4). 2. Validate all 23 CORE-LD invariants (I1–I23) via urs_conformance.py. 3. Produce canonical JSON-CORE-LD output per §5.1. 4. Reject documents violating any invariant, with a diagnostic naming the invariant and the offending entity. 5. Resolve the CORE-LD @context to its published URI and enforce the defined-term rule (§3.3). 6. Round-trip any valid document per §7 without loss below the claimed identity level.
10.2 Conformance levels
| Level | Requirements |
|---|---|
| L1 Structural | I1–I11 pass; parse + frame correctly (RT-1) |
| L2 Identity | L1 + I12–I15 pass; canonical hashing per §5.2 correct (RT-2) |
| L3 Constitutional | L2 + I16–I23 pass; full provenance + canonicalization (RT-3) |
11. Registry
| Field | Value |
|---|---|
| Binding name | `JSON-CORE-LD` |
| Encodes | `CORE-LD v0.1.0` |
| Encoding format | JSON (RFC 8259 subset per §2) |
| Media types | `application/json` (canonical), `application/ld+json` (linked-data view) |
| Canonical @context | `https://specs.initialcore.net/ns/core-ld.jsonld` |
| Codec identifier | As assigned in the URS Canonicalization codec registry; when DAG-addressed, maps to multicodec `dag-json` (0x0129) |
| Conformance suites | `urs_conformance.py` (I1–I23), `profile_conformance.py` (profile extensions) |
JSON-CORE-LD v0.1.0 — July 31, 2026. Draft. Encodes CORE-LD v0.1.0. Reference encoding binding of the DAG--LD family; binary companion: CBOR-CORE-LD v0.1.0.*