Prompt and scope
A team wants to author data contracts and knowledge-graph configuration in YAML-LD while continuing to serve existing JSON-LD consumers. Explain how you would verify semantic equivalence, handle YAML feature limits, secure parsing, and set adoption gates.
W3C YAML-LD 1.0 is currently a Working Draft. It defines YAML-LD as conventions on top of YAML that use JSON-LD syntax, semantics, and APIs, while constraining richer YAML features so every YAML-LD document can be represented as JSON-LD. The question tests data-format migration and interoperability without assuming the draft is a final standard.
What the interviewer evaluates
The interviewer wants you to separate YAML surface syntax from JSON-LD graph semantics and define normalization, differential testing, parser safety, and version governance. A strong answer states that a Working Draft is not a stability commitment and that readability alone does not prove adoption value.
Clarifying questions before answering
- Do consumers read YAML directly, or do they only accept JSON-LD RDF graphs?
- Which JSON-LD keywords, contexts, remote documents, and namespaces are required?
- Are anchors, aliases, custom tags, or timestamp types present?
- What are the parser trust boundary, resource limits, and remote
@contextpolicy? - What compatibility window, version negotiation, rollback, and final approver are required?
30-second answer framework
“I would treat YAML-LD as a Working Draft input format and freeze the supported subset and JSON-LD version. Every sample would pass a safe YAML parser, YAML-LD constraint validation, conversion to JSON-LD, RDF dataset normalization, and semantic comparison; features that cannot be represented equivalently would be rejected. Remote contexts would use an allowlist and pinned cache, with limits on aliases, depth, size, and other resource access. The new format would start in read-only dual-write or shadow parsing, expanding only after graph semantics, errors, performance, and security gates pass.”
Step-by-step deep answer
1. Define the input and output contract
Put the YAML-LD document, generated JSON-LD, RDF dataset, and consumer API version in the contract. Freeze supported JSON-LD keywords, context sources, encoding, and numeric rules; arbitrary YAML is not YAML-LD. Record the specification and test-suite versions whenever the draft changes so different parsers cannot silently diverge.
2. Constrain YAML features first
W3C notes that YAML is more expressive than JSON, so YAML-LD supports a constrained subset that maps to JSON-LD. Reject or explicitly forbid custom tags, ambiguous timestamp types, cyclic aliases, and implementation-specific types; allow anchors and aliases only when their expanded structure and JSON representation are stable. Encode these limits as executable lint rules rather than relying on author memory.
3. Verify graph semantics, not text similarity
Safely parse YAML-LD, convert it to JSON-LD, expand contexts, and produce an RDF dataset. Compare the triple or quad sets with a normalization algorithm. Property order, YAML indentation, and JSON key order should not change the result; node identifiers, language tags, types, and list order require explicit checks. Preserve a minimal reproducer for every semantic difference instead of hiding it with a string diff.
yaml = safe_parse(input, aliases=false, max_depth=32, max_bytes=1048576)
yaml_ld = validate_yaml_ld_subset(yaml)
json_ld = to_json_ld(yaml_ld)
left = normalize_rdf(json_ld)
right = normalize_rdf(reference_json_ld)
assert left == right4. Design parser security boundaries
Disable arbitrary file, network, and code-execution capabilities; allow remote @context only from an allowlist with pinned versions and size limits. Limit document size, nesting depth, alias expansion, parse time, and memory, and record parser versions and context hashes. Return structured errors with locations on failure; never write unvalidated data to a graph store or downstream repository.
5. Preserve existing consumers
Build a compatibility matrix for every JSON-LD consumer, covering context resolution, types, language tags, lists, nulls, and unknown fields. Initially keep JSON-LD as the canonical output and use YAML-LD only as author input or a shadow path; compare conversion failures, graph differences, latency, cache hits, and resource use. Unsupported consumer features must fail in CI rather than silently degrade in production.
6. Set adoption gates and rollback
Define semantic consistency, critical-fixture pass rate, security scans, parser p95, resource limits, and consumer error-rate thresholds in advance. Pause expansion when the Working Draft or test suite changes, keeping the old JSON-LD generator, context cache, and input version. Require repeated tests, upgrade drills, audit records, and data-owner approval before adoption; do not describe a draft as a stable standard.
High-quality sample answer
I would treat the YAML-LD 1.0 Working Draft as a controlled input format and freeze the supported JSON-LD version, keywords, contexts, and YAML subset. The pipeline would use a safe parser with limits on size, depth, aliases, and network access; after validation it would convert to JSON-LD, expand contexts, normalize an RDF dataset, and compare graph semantics with the existing JSON-LD baseline. Key order and indentation must not matter, while node identifiers, types, language tags, and list order must match. Remote contexts would use an allowlist, pinned cache, and hash audit. Initially JSON-LD would remain the canonical output while YAML-LD runs in shadow parsing, with gates for semantic differences, parse errors, p95 latency, memory, and consumer errors. Any unrepresentable YAML feature, failed security scan, or draft-upgrade regression pauses expansion and rolls back to the old generator. Final approval would rely on a versioned test suite and a data-owner sign-off, not on treating a Working Draft as a final standard.
Common mistakes
- Treating shorter or more readable YAML as proof of interoperability → readability is not graph-semantic equivalence → compare normalized RDF datasets.
- Using a generic YAML deserializer directly → it may accept types or aliases outside the YAML-LD subset → enable safe mode and constraint linting.
- Only running a text diff → key order and indentation create false differences → compare nodes, types, language tags, lists, and quads.
- Allowing arbitrary remote contexts → supply-chain, availability, and drift risks become uncontrolled → use an allowlist, cache, hashes, and limits.
- Calling a Working Draft a stable standard → the draft may change → version the tests, stage the rollout, and keep rollback output.
Follow-up questions and responses
Why not retain every YAML feature?
The goal is for a YAML-LD document to be representable as JSON-LD. Types, tags, or cyclic structures without stable mappings break interoperability and should be rejected or deferred to an extended profile.
How do you determine that two documents have the same semantics?
Convert and expand contexts, produce normalized RDF datasets, and compare node identifiers, predicates, objects, types, language tags, and list order rather than raw text.
Why pin and allowlist remote @context resources?
They affect parsing and introduce network, supply-chain, and version-drift risks. Fixed sources, versions, hashes, and timeouts make results reproducible and reversible.
When can YAML-LD become the primary authoring path?
After constraint validation, semantic diffs, security scans, performance, consumer compatibility, and rollback drills pass repeatedly, with the draft version, test suite, and change owner locked.
What if a specification update creates a small graph difference?
Pause expansion, preserve a minimal reproducer, specification version, and context hash, and determine whether the change is intended. Keep producing the old JSON-LD until compatibility policy and data-owner approval are complete.