Reading edition of the normative original, pinned to revision 61e75e9aa9a8719dfb480bf1f5226553b3a21d70. This edition does not define a new specification revision.

skosovsky/okf-v0.2 graph projection contract

This directory is the executable toolkit contract for projection version 0.2. It is not an upstream OKF ontology. The machine-readable closed classes define every allowed predicate with explicit minimum/maximum cardinality, IRI/literal kind, and datatype. Identity, collection, deduplication, and JSON-LD/N-Triples parity rules are also frozen in v0.2.json and checked by package tests.

Concept IRIs use local:bundle: plus the URL-path-escaped concept ID. Synthetic nodes use the reserved urn:skosovsky:okf:graph:v0.2: namespace. Synthetic components are unpadded base64url values, so synthetic identities are injective and cannot collide with concept IRIs or with each other through delimiter ambiguity.

Zero values do not create collection predicates. JSON-LD compacts one value to a scalar/object and uses an array for multiple values. N-Triples emits one triple per value. Nodes sharing a synthetic resource identity are coalesced; identical property values are emitted once.

The JSON-LD document has only @context and @graph at its root. Projection metadata is a normal Projection node inside @graph, so both JSON-LD and N-Triples describe the same RDF default graph.

Every renderer exposes Render<Format>Context and Render<Format>WithOptionsContext. Cancellation is observed during version assertion, projection traversal, stable ordering, escaping, and chunked output. The historical methods delegate with context.Background() and keep their exact byte contract. A writer error or short write already observed by a renderer takes precedence over cancellation observed by that same write. JSON-LD is encoded deterministically as a stream rather than by constructing one monolithic output buffer.

Dates and datetimes receive XSD datatypes only when bundle reports them as valid typed values. Graph renderers do not parse raw date text. YAML relations are emitted as ToolkitExtensionRelation observations, including valid unresolved targets with targetExists=false.

stalenessAsOf and stale are evidence derived from a valid stale_after only when the caller supplies explicit Options.AsOf. Without it, staleness remains unevaluated and the renderer never consults the wall clock. An absent or malformed declaration emits none of those predicates. Provenance sources require a complete valid source observation with a resource. Shared and per-source usage windows are emitted only when the complete selected window is valid.

An AttestedComputationContract is emitted only for an exact type: Attested Computation document. Its mandatory computationMode preserves the bundle-owned payload state: inline, file, absent, ambiguous, or malformed.

Computation parameters, executor contracts, and attester contracts are emitted only from complete valid bundle observations. In particular, an absent or malformed required boolean never becomes a fabricated false.

Claim attribution uses the shared CommonMark reference-label normalization. Each ProvenanceSource retains its raw sourceID; ClaimAttribution.sourceID is the normalized identity. A normalized-label collision is a deterministic many-to-many join: attributedSource contains every valid projected source with that normalized identity, never an order-dependent first match.

Every concept has an effectiveStatus. An absent declaration resolves to stable; a valid declaration resolves to its open-string value; a malformed present declaration resolves to the graph sentinel unresolved while its raw display value remains available as declaredStatus.

Package tests use github.com/piprate/json-gold/ld as a standards processor to convert emitted JSON-LD to RDF, reject named-graph drift, and compare its default-graph semantic triple set exactly with N-Triples. A frozen Appendix A RDF golden anchors the full canonical projection independently of either renderer.