Prompt and scope
Design a renderer that generates an editable form from an RDF data graph and a SHACL shapes graph. How would you choose the focus node and root shape, aggregate property constraints, select widgets, resolve multilingual labels, and keep validation explainable?
The question maps to the W3C First Public Working Draft of SHACL 1.2 User Interfaces, published on 26 May 2026. It uses SHACL shapes and constraints to generate view and edit interfaces for RDF resources, with processing models for components, label resolution, layout hints, and widget scoring. The draft may change, so distinguish the specification boundary from product implementation decisions.
What the interviewer evaluates
The interviewer is looking for a clear data flow among the shapes graph, data graph, focus node, and node shape; correct aggregation of multiple property shapes on one path; and deterministic, extensible widget selection. Cover language fallback, explainable failures, cache invalidation, authorization, and the transaction boundary. A strong answer notes that the draft does not define visual styling, a submission protocol, a complete validation workflow, or accessibility requirements; the application must supply those pieces.
Clarifying questions before answering
- Are only the data and shapes graphs supplied, or does the caller also provide a focus node and root node shape?
- Is this view, edit, or query mode? Can one focus node match multiple shapes?
- Who owns the widget catalog, and can tenants extend the scoring graph?
- What are the preferred and fallback languages, and what is the local-name rule when no label exists?
- Does saving require an atomic transaction, concurrency control, authorization, and independent SHACL validation?
A 30-second answer framework
“I would split the system into input parsing, shape indexing, component generation, widget selection, label resolution, validation display, and a submission adapter. The renderer requires a data graph, shapes graph, focus node, and node shape; if the last two are missing, the application performs automatic selection and exposes uncertainty. A property component aggregates constraints by focus node and property path, then chooses a widget through explicit declarations, accept matchers, and scoring. Every decision records its rule and score, while labels follow the user’s language fallback. Rendering is the specification concern; storage, authorization, transactions, and styling belong to the application.”
Step-by-step deep dive
1. Fix inputs and execution modes
Make the data graph, shapes graph, focus node, and node shape explicit inputs. All four mean manual mode; missing a focus node or node shape triggers automatic mode, with the result written to diagnostics. View and edit can share shape resolution, but an editor also needs dirty state, undo, and concurrency policy.
2. Build shape and path indexes
Preprocess node shapes, property shapes, targets, property paths, and constraint components. An index key should include the shape IRI, focus node, and path. Aggregate multiple property shapes for the same focus node and path while retaining provenance and severity, so one constraint cannot silently overwrite another.
3. Generate node and property components
A node component represents a focus node; a property component represents the merged constraints for one path. Derive the field set from the shapes, then apply grouping, ordering, roles, and conditional shapes. Preserve edit semantics for complex paths. If a path cannot safely map to one field, downgrade to a read-only viewer or require an explicit product edit strategy.
4. Select widgets deterministically
Check an explicitly declared widget and its accept matcher first. If it is rejected, call the scoring function, collect candidates from the scoring graph, and break ties with stable score, priority, and IRI ordering. The scoring inputs include the focus node, data graph, shapes graph, property shape, and scoring graph. Missing mandatory inputs or malformed score instances should produce a structured error instead of a guessed widget.
explicit widget -> accept matcher -> score candidates -> stable tie-break
-> label resolution -> component tree -> validation messages5. Resolve languages and labels
Label resolution considers the shapes graph, data graph, application environment, and user preferences. Choose the preferred language first, then follow the configured fallback order. If no label is suitable, use the IRI local name or a safe product-defined placeholder. Field labels, enumeration values, and validation messages should share one language context and record the selected source for diagnosis.
6. Keep validation and persistence in the right boundary
The SHACL UI draft describes widget generation and processing; it does not define a submission protocol, storage transaction, complete error handling, or authorization model. The application should invoke an independent validator before and after submission and display the focus node, path, constraint component, and message provenance. Use versioned or conditional writes to avoid overwriting concurrent edits; preserve the user’s edit state and a structured retry result on failure.
7. Add observability, caching, and security
Shape changes invalidate component and widget caches. Cache keys should include shape version, data-graph version, language, and authorization context. Restrict remote IRIs, HTML rich text, and autocomplete sources so untrusted RDF cannot become scripts or unsafe links. Log shape selection, widget decisions, validation latency, and downgrade reasons without logging the complete sensitive graph.
High-quality sample answer
I would define four renderer inputs: data graph, shapes graph, focus node, and node shape. If the last two are absent, the caller performs automatic selection and returns an explainable decision. Preprocessing indexes node shapes, property shapes, and paths, then aggregates constraints for each focus-node/path pair with provenance. After building the component tree, widget selection checks explicit widgets and accept matchers before scoring candidates; stable score, priority, and IRI ordering resolve ties. Label resolution uses the user’s preferred and fallback languages across the shapes graph, data graph, and environment, with a safe local-name fallback. Every decision records its rule source, and validation results retain focus node, path, and constraint identity. Persistence, authorization, concurrency, and transactions stay in the application layer, as do styling, submission protocol, and accessibility requirements outside the draft. This yields consistent forms across implementations while allowing the adapter layer to evolve with the draft.
Common mistakes
- Treating SHACL UI as a complete low-code platform → the scope is too broad → separate rendering, validation, persistence, and authorization.
- Taking only the first property shape → constraints disappear silently → aggregate by focus node and path with provenance.
- Choosing widgets randomly or by traversal order → identical inputs render differently → define scoring, priority, and stable tie-breaking.
- Reading only
rdfs:label→ language fallback fails → implement language resolution and record the source. - Rendering RDF text as HTML → script injection risk → escape untrusted values and restrict viewer capabilities.
- Closing the form after a successful write → concurrent or validation failures lose edits → use conditional writes and preserve failure state.
Follow-up questions and responses
What if a focus node matches multiple root shapes?
Have the application provide an explicit selector or business priority. The renderer should auto-select only when rules are sufficiently deterministic and return candidates with reasons; traversal order is not a business rule.
How do you break a tie between equally scored widgets?
Compare explicit accept rules and product priority first, then use stable widget IRI or registration order. Version the tie-break policy so deployments do not silently change the interface.
Why not persist RDF inside the renderer?
The renderer can own edit state, but submission protocol, transactions, authorization, and conflict resolution belong to the application data layer. Separation enables reuse and lets the server validate untrusted input again.
What if a complex property path cannot map to an input field?
Show the path and value read-only and state that no edit strategy exists. Enable editing only after the product supplies a safe read/write transform and conflict policy; do not expose a field that appears writable but cannot be persisted.
How do you test consistency across implementations?
Fix the data graph, shapes graph, language preferences, and scoring graph, then assert the component tree, label source, widget IRI, ordering, and error classes. Add conformance tests and property-level regression cases for downgrade paths.