Closed gkellogg closed 5 years ago
@gkellogg This seems reasonable and useful to me.
Would sealing be a context-level-only feature? IOW, do you propose allowing some terms in a context to be sealed but not others?
Would sealing be a context-level-only feature? IOW, do you propose allowing some terms in a context to be sealed but not others?
alternatively, one could also split the context into one sealed part and an unsealed one, and just import both right?
I imagine so, although the interweaving might be difficult... I'd have to work through some examples.
This issue was discussed in a meeting.
RESOLVED: Defer #20 for TAG review for cross-specification issues of signing on the web ; confer with security regarding SRI and credentials regarding LDS vs byte hashing
ACTION: Rob Sanderson to create context signature issue, related to #20
This issue was discussed in a meeting.
Hello!
An idea was proposed at the meeting at TPAC that this issue could be addressed by simply ordering "extension" contexts first and "core" contexts last in an @context
array. We've considered it and it doesn't work for a number of reasons.
First, there's the aesthetics of it (people would prefer a "core" @context
to come first in the array) but there are also more serious technical problems. Here's one example:
Here a SpecificCredential
with a scoped context for the issuer
property overrides the base definition for issuer
with the extension -- causing evil/confusion. The issuer
property MUST NOT be overridden, yet it is.
I think it would probably be best to create a "sealed"/"frozen" @context
feature and, while we're at it, make it use the more "expected" order of precedence (for this feature). I think this feature is really essential for JSON-LD adoption as "the way" to do extensions in specs for open world data models.
@dlongley thanks for that example! Scoped contexts do introduce a whole new layer of complication/confusion/unexpectedness... That said, I'm not sure the current array ordering is that unintuitive/unexpected.
Developers (especially general Web developers) are very familiar with "cascading" thanks to CSS. Things currently work this way with JSON-LD @context
values.
It's also the way JavaScript (ECMAScript)'s Object.assign()
works--last one wins:
a = {'test': 'ing'};
b = {'test': 'er'};
console.log(Object.assign({}, a, b));
// Object { test: "er" }
And, it's also the way ES6's Object Rest/Spread Properties work:
a = {'test': 'ing'};
b = {'test': 'er'};
console.log({...a, ...b});
Consequently, I'd find flipping the order more confusing and intuitive--and out of keeping with the surrounding code one would write to create the local context. So, I'd be 👎 on flipping that order--especially between JSON-LD minor point releases. Sorry.
I'll leave the continued discussion around sealed contexts--especially as it relates to the scoped context example you gave for another time. 😃
So, I'd be -1 on flipping that order--especially between JSON-LD minor point releases. Sorry.
To be clear, I wasn't suggesting we flip the order for term definitions, just that sealed contexts should apply left to right ("first sealed context wins"). I think it would be odd for them to apply right to left ("last sealed context wins").
Yep, I guess where we did make a mistake at TPAC is to think only the way context works in 1.0. I am a bit neutral about the problem of whether one type of ordering is more natural than the other; I can see the points of @BigBlueHat. However, as the example of @dlongley shows, the problem of scoped contexts shows the limits of this approach anyway, and makes the problem about right order possibly irrelevant... :-(
I.e., we may be back to the drawing board on that one.
@dlongley musing on this some more (as I work on Verifiable Claims Data Model tests), and I'm wondering how much of this is solely "scoped context" related.
For example, I altered the example you posted earlier, and made the VerifiableCredential
definition use it's own (rather redundant looking) scoped context:
http://tinyurl.com/ycldnsyv
"VerifiableCredential": {
"@id": "base:VerifiableCredential",
"@context": {
"issuer": {
"@id": "base:issuer"
}
}
}
That, consequently, "fixed" the problem (in this narrow scenario). 😉
So, what I'm wondering now is:
@type
" is essentially prevented (or limited) on that particular context's terminology (i.e. VerifiableCredential
can't have it's context's terms overridden)--perhaps that's automatic on the last, authoritative context.Thoughts?
@BigBlueHat,
- can this "sealing" be done now simply with more verbosity (however annoying)--as done above?
- could that verbosity be removed by a new mechanism to express that "scoping on @type" is essentially prevented (or limited) on that particular context's terminology (i.e. VerifiableCredential can't have it's context's terms overridden)--perhaps that's automatic on the last, authoritative context.
Thoughts?
I suspect all of the requirements discussed in issue #98 likely can't be covered. Even so, I'm also a little apprehensive about creating contexts that may appear to have useless cruft in them -- instead using the clarity that a @seal
feature would have.
It seemed like we arrived at a pretty good/coherent path forward for the @seal
feature in #98.
Some proposed content to be turned into specification text if it meets the use cases...
@sealed
that has a boolean value. The default, if not present, is false.@sealed
is encountered in a context as part of a term definition, it signals the processor that any subsequent attempt to redefine that term should be treated as an error.@sealed
is encountered at the top level of a context, not part of a term definition, it is a shortcut for the situation that every term definition in the context should be treated as if it contained @sealed: true
Thus, some examples...
{"@context": {"label": {"@id": "rdfs:label", "@sealed": true}}}
This context defines label
to be rdfs:label
, and any subsequent context that tries to define label
will generate a processor error.
{"@context": {"@sealed": true, "label": "rdfs:label"}}
This is equivalent to the first example.
{"@context": {"label": {"@id": "rdfs:label", "@sealed": true},
"value": {"@id": "rdf:value"}}}
Label is sealed, but value is not sealed.
{"@context": {"@sealed": true, "label": "rdfs:label",
"value": {"@sealed": false, "@id": "rdf:value"}}}
Equivalent to the previous, just in reverse
{"@context": {"sealed_data": {"@context":
{"@sealed": true, "label": "rdfs:label"}}}}
Within sealed_data
, label
is sealed to be rdfs:label, but can be redefined in contexts other than within sealed_data
.
{"@context": {"sealed_data": {"@id": "rdf:value", "@sealed": true,
"@context": {"sealed_data": "eg:data"}}}}
An error, as sealed_data is still sealed. (?)
{"@context": {"wild_west": {"@id": "eg:playground", "@sealed": true, "@context": null}}}
You can't redefine wild_west
because it is sealed to be eg:playground
, but within the wild_west
there is no defined context (it has been nulled out) and thus anything goes ... including redefining sealed terms. This should only work when the resetting and the sealing are in the same context.
{"@context": [
{"sealed_data": {"@id": "rdf:value", "@sealed": true"},
null,
{"sealed_data": {"@id": "eg:playground"}
]}
Error state, as the null would remove a sealed term.
Questions arising:
id
being aliased to @id
cannot be overridden? Propose that the answer is yes.@vocab
? Propose that the answer is no, it's only the definitions of terms that are sealed.@sealed
(c.f. #108) to seal it in your usage? Propose defer until #108 is resolved.(Tag @dlongley to take a look)
I agree with Rob's examples.
Can you seal alias definitions, such that id being aliased to @id cannot be overridden? Propose that the answer is yes.
Yes.
Can you seal the default vocabulary definition via @vocab? Propose that the answer is no, it's only the definitions of terms that are sealed.
I think "no" makes more sense here, but I'm open to an argument for "yes".
Can you annotate a context with @sealed (c.f. #108) to seal it in your usage? Propose defer until #108 is resolved.
Also +1 to deferring.
Another example for clarity on wild_west
:
{
"@context": [
{"wild_west": {"@id": "eg:playground", "@sealed": true, "@context": null}},
{"wild_west": {"@context": "http://schema.org"}}
]
}
This is not an error and causes the scoped context for "wild_west" (anything nested under that term) to be "http://schema.org".
Regarding this:
{"@context": {"sealed_data": {"@id": "rdf:value", "@sealed": true,
"@context": {"sealed_data": "eg:data"}}}}
An error, as sealed_data is still sealed. (?)
I'm not convinced that should be an error given that it's in the same document. This seems like something someone may want to do. I would expect the sealing here to prevent other documents from changing the scoped context.
I think we need a separate issue for the partial redefinition case for adding a context to wild_west
. Will create one.
This issue was discussed in a meeting.
ACTION: Rob Sanderson to document simple input and expected processing of them
ACTION: Dave Longley to review azaroth’s text and add further examples
{ "@context": { "sealed_data": { "@id": "rdf:value", "@sealed": true, "@context": { "sealed_data": "eg:data" } } } }
An error, as sealed_data is still sealed. (?)
I would agree this is a an error; I am not sure I understand @dlongley's remark "I'm not convinced that should be an error given that it's in the same document.". More exactly, how would one define this exception in a spec?
I'm not sure it's an error either, as the top-level sealed_data
is sealed, and part of what's sealed is hat it introduces a new context. I think it effectively changes the interpretation of sealed_data
(or whatever else is defined) under the first use of sealed_data
without unsealing anything.
The only thing that unseals is to have a scoped context include null
, so for example:
{
"@context": {
"sealed_data": {
"@id": "rdf:value",
"@sealed": true,
"@context": [null, {"sealed_data": "eg:data"}]
}
}
}
both unseals and introduces a new term definition. (altho, eg
cannot then be defined as a term, so would look like an IRI scheme`).
I'm not sure it's an error either, as the top-level sealed_data is sealed, and part of what's sealed is hat it introduces a new context. I think it effectively changes the interpretation of sealed_data (or whatever else is defined) under the first use of sealed_data without unsealing anything.
Yes, this was my interpretation as well. And it seems like it enables more use cases. The scoped context is part of the sealed definition and it isn't null
(which would unseal it). Whatever is in that @context
applies even if it means providing a scoped term definition for the same term.
Interesting corner case: what if two sealed contexts are used, and a term in one of them contains a scoped context which includes null
. It probably shouldn't be able to remove all contexts, so this would just be ignored. For example:
{
"@context": [
{"term1": {"@id": "http://example.com/term1", "@sealed": true}},
{"term2": {"@id": "http://example.com/term2", "@sealed": true, {"@context": null}}
],
"term2": {
"term1": "This should still evaluate to http://example.com/term1",
"term2": "This may still evaluate to http://example.com/term2 if the @context: null above was ignored"
}
}
The problem is, how to detect this? The simplest implementation is to seal terms when they include @sealed
or their contexts includes @sealed
and prevent (with a warning) any attempt to change it later. When setting a new context, we can prohibit this if the active context contains any sealed terms, unless setting it to null
(or something starting with null
) if it comes from a scoped context of a sealed term. I'm not sure how to do this when multiple contexts are involved.
I'd like to iron out the cases that do NOT have @context:null first. Then we can look at unsetting.
For the processing, is the sealing before or after processing scoped contexts?
If it's after, then the sealed_data
example works (in my head) as expected by @dlongley and @gkellogg. If it happens before then it works (in my head) as expected by myself and @iherman. Is this the correct reasoning?
I'm not sure I would express this in terms of "before / after", but I agree with @gkellogg 's argument: "the top-level sealed_data
is sealed, and part of what's sealed is that it introduces a new context".
@azaroth42 you will have to explain this a bit... you mean whether sealing happens before or after the setting of the @id
is done (in our example)?
When a processor encounters the term definition, it has a choice of whether to process @sealed
first or @context
first. If it processes @context
first, then it descends into the scoped context and processes the terms there (which might in turn have scoped contexts, and sealing) before processing the sealing.
In the example, my understanding is thus that sealed_data
at the top level would not be sealed if @context
is processed before @sealed
.
Sorry, this is still very abstract for me. I went back to the expansion algorithm in the current draft.
Step 6 is about merging an embedded context; my understanding is that it should failed if the active property is sealed.
Step 9.5 is about merging a scoped context from the term definition, when traversing a property. This one should, I think, succeed even if the traversed property is sealed. Indeed, the scoped context comes from the term definition itself, which is also where the sealing comes from. So, to rephrase @gkellogg's comment above, we can trust that scoped context as being part of what was sealed.
EDITED: I was mistaken on the different steps. Replaced "Step 7.1" by "Step 9.5" above. I'm actually unsure about how 7.1 should handle this...
@azaroth42 asks:
For the processing, is the sealing before or after processing scoped contexts?
As @pchampin said, I believe the sealing is done in the term definition phase. Any term, sealed or unsealed, may define a scoped context, it's only when it comes into play during expansion that it might come into conflict (warning, not error IMO) if used to redefine a sealed term.
I have it implement, but not yet tested, and the changes are fairly localized:
@sealed
is true, pass it to every call to Create Term Definition.@sealed
true, or Create Term Definition was called with @sealed
true, set @sealed
true on the term definition.null
, skip the step if the active context has any sealed term unless it was invoked from the scoped context coming from a sealed term (about three spots in the Expansion Algorithm. (note the hole in the logic I noted in
https://github.com/w3c/json-ld-syntax/issues/20#issuecomment-457028351).I'll see if I can get spec text and some tests added before tomorrow's call.
@gkellogg,
Interesting corner case: what if two sealed contexts are used, and a term in one of them contains a scoped context which includes null. It probably shouldn't be able to remove all contexts, so this would just be ignored.
Apologies to @azaroth42 for continuing down this path, but in thinking about your corner-case...
It seems like, since the original sealed context did not define term2
at all, there would be no expectation for what might appear underneath that term. Using sealed contexts is primarily (exclusively?) tied to making JSON-LD more compatible with JSON-only processors that rely on tree structures. This means that no such software that is relying on the first sealed context would ever traverse into term2
(as it is not defined). So term2
should be free to clear what is underneath it.
It may be that specifying a scoped context of @context: null
should always be acceptable in new term definitions. If term2
were not new (i.e. it was defined and sealed by the first context), then its definition would be ignored as expected.
@dlongley said:
This means that no such software that is relying on the first sealed context would ever traverse into
term2
(as it is not defined). Soterm2
should be free to clear what is underneath it.
The implication is that, when traversing into an unsealed term, the active context is cloned and all term definitions are unsealed. This could work, but it seems it will have a potentially big impact on memory and performance. Perhaps there's away to parameterize the expansion algorithm invocation, to cause all every subsequent attempt to update the context to look like it came from a sealed term.
It may be that specifying a scoped context of
@context: null
That would fall out of the previous logic, as we don't actually check for setting the context until expanding.
Just for my understanding:
{
"@context": {
"sealed_data": {
"@id": "rdf:value",
"@sealed": true,
"@context": {
"sealed_data": "eg:data"
}
}
},
"sealed_data" {
...
"sealed_data" {
...
}
}
}
the first appearance of "sealed_data"
(on the top level) would expand into "rdf:value"
while the second appearance would become "eg:data"
. Actually, I presume this is unrelated to sealing: this would be valid without "@sealed"
, too.
However
{
"@context": [{
"sealed_data": {
"@id": "rdf:value",
"@sealed": true,
"@context": {
"sealed_data": "eg:data"
}
}
}, {
"sealed_data" : {
"@id" : "eg:something_else"
}
}]
}
would be an error, because the sealing is switched on after all the embedded contexts are processed.
Is this correct?
In thinking more about your "corner-case", @gkellogg, I think it helps highlight more about what we're trying to do with this feature.
This new sealed
feature is intended to enable processor-enforcement of fixed semantics in JSON(-LD) of the sort typically only described in specifications. Specifications that use JSON and intend to allow for extensibility describe a set of terms with fixed semantics that must not change unless:
{
"sealed1": {
"sealed2": {
"sealed1": "this sealed1 has a new meaning"
}
}
}
This is what @iherman's example is about above.
Common patterns for extensibility here include:
{
"sealed1": "foo",
"sealed2": {
"sealed3": "bar"
},
"sealed4WhereExtensionsGo": { /* anything */ }
}
This is the sort of pattern for which defining a specific @sealed
term with a scoped @context: null
would apply.
{
"sealed1": "foo",
"sealed2": {
"sealed3": "bar",
"extension1": "baz",
"extension2": {
"extension3": "moo",
"extension4": { /* anything */ }
}
},
"extension5": "woof",
"extension6": { /* anything */ }
}
The latter applies to your "corner-case", which I don't think is so much in a corner anymore, but rather quite common. This hints that we should treat any previously undefined terms as if they had been specified with a scoped This hints at a rule that terms should "own" their own scopes. This means that any new terms (that were previously completely undefined) should be able to define whatever they want in a scoped context. This rule would only apply to nesting, however -- not "type-based scoping" because it leads to this problem.@context: null
by default.
@iherman,
Is this correct?
Yes, I agree with everything you said above.
@iherman i believe both cases work the same; not, “errors”, per se, but perhaps a warning, and processing is aborted. As written, the only way to redefine a sealer term is to clear out the context. In your first example, the scoped context is handled during expansion and looks like an attempt to redefine the term, so is ignored. The second case does the same, but not during the expansion process.
@dlongley to treat undefined terms (or unsealed defined terms?) as if the context is wiped out underneathwout be a major departure from current behavior, and would yield unexpected results. I would say, instead, as we discussed earlier, that under properties that are. It sealed, previously sealed terms are effectively unsealed, but their definitions remain, including any scoped contexts that may define sealed terms.
Do I detect a contradiction between the answer of @dlongley and @gkellogg here?
@dlongley agreed with what I said. Ie, just to make it clear, this means
{
"@context": {
"sealed_data": {
"@id": "rdf:value",
"@sealed": true,
"@context": {
"sealed_data": "eg:data"
}
}
},
"sealed_data" {
...
"sealed_data" {
...
}
}
}
is fine. However, @gkellogg seems to say this is an error/warning. Which is it? Or more exactly, how should our spec go, ie, should this be correct or not correct?
I created test cases and spec text based on my understanding of our discussions that the only way to redefine a term is to clear out the context, something that can only be done from a scoped context within a sealed term.
Note that scoped contexts are not processed when they are defined, but when they are encountered during expansion, as if they had been specified inline.
If we want to do something different, we could say that scoped contexts coming from sealed terms can redefine sealed terms, but IIRC, we hadn’t discussed that.
Sorry to be a drag, @gkellogg, but it is very difficult to understand the spec text as included in the API. Would it be possible to have a draft that would appear in the syntax document (that is what an end-user, like your truly, would read...)
@gkellogg,
...to treat undefined terms (or unsealed defined terms?) as if the context is wiped out underneathwout be a major departure from current behavior, and would yield unexpected results.
Hmm, I didn't mean to suggest that. So I shouldn't have said we'd treat them as if the scoped context was @context: null
by default. Rather, what I meant by that was that a new term should be able to redefine whatever it wants via a scoped context. The rule I think I'm suggesting is that terms always "own" their own nested scopes. This rule would only apply to nesting, however -- not "type-based scoping" because it leads to this problem.
Perhaps the "type-scoping" difference (vs. nesting) I mention above could be remedied by sealing type definitions in a manner similar to what @BigBlueHat did here: https://github.com/w3c/json-ld-syntax/issues/20#issuecomment-454485321
This issue was discussed in a meeting.
ACTION: Pierre-Antoine Champin to write spec text of his mental model
On the "bikeshedding" front, we may want to consider the term "frozen" in place of "sealed." From MDN:
Existing properties in objects frozen with
Object.freeze()
are made immutable. Objects sealed withObject.seal()
can have their existing properties changed. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal#Comparison_to_Object.freeze()
I've not done a wider survey of other languages yet, but as JSON's next-of-kin is JavaScript, it seems prudent to consider naming that matches there as closely as possible.
That's a good point; I agree that terminology is important.
That being said, I like the metaphor of the seal, as I have used it extensively in explaining how the processing should be done. I can't find an equivalent with a "frozen" metaphor.
[[failed attempt to make a pathetic pun about seals, see ice and freezing...]]
Maybe allow 10 minutes for bikeshedding on the call tomorrow. I can go either way.
This issue was discussed in a meeting.
Following up on the question @iherman raised at the end of yesterday's discussion, the need for a json-ld author to redefine select schema.org terms is real - it will create more work (or confusion for simple json developers) if there is no easy way to override a decision by schema.org to seal their context - e.g., could lead authors to clone and maintain their own variants of schema.org context.
Illustration -- As has come up in the WG previously, schema.org has many properties with a range that encompasses multiple data types, e.g., per current schema.org documentation both Text and URL are listed as values expected for the properties genre, artMedium, artworkSurface, artform, fileFormat. But the schema.org context specifies only URL (@id) when defining each of these terms, e.g. from the current schema.org context document:
"fileFormat": { "@id": "schema:fileFormat", "@type": "@id" }
So, in one or our applications here at Illinois we routinely reference schema.org context document and then redefine these 5 terms, e.g. (for fileFormat):
"@context": [
"http://schema.org/",
{
"s": "http://schema.org/",
"fileFormat": { "@id": "s:fileFormat", "@type": "s:Text" }
} ]
For full example (we have about 4,500 of these), see: http://imagesearch-test1.library.illinois.edu/jsonld/10189v2.json
Current JSON-LD playgrounds (both) accept these redefinitions and understands our use of text strings as values for these properties. So the following line in our json-ld instance
"fileFormat": "image/jpg"
is expanded by the playgrounds as we want:
"http://schema.org/fileFormat": [
{
"@type": "http://schema.org/Text",
"@value": "image/jpg"
} ],
If we fail to redefine these schema.org terms -- or if in the future our attempt in local context to redefine these terms are ignored because schema.org someday chooses to seal their context, then the playgrounds turn our strings into relative URLs. A version of our file without the redefinitions is here: http://imagesearch-test1.library.illinois.edu/jsonld/10189v3.json
In this case (no redefinition) the same key-value in the instance as above:
"fileFormat": "image/jpg"
is expanded by the playgrounds this way (NOT the way we want):
"http://schema.org/fileFormat": [
{
"@id": "https://json-ld.org/playground/image/jpg"
} ],
Of course we can effectively work around the default term definitions on a case by case basis by using object values for the un-redefined properties and explicitly specifying @value and @type:s:Text ourselves (will this technique still work if term definition is sealed?).
But this is not the ideal solution to prescribe (especially for simple json developers) and notably the Google SDTT does not accept this usage (one of a few issues with the tool which I don't think actually looks at context at all).
So, personally I would appreciate a more flexible seal mechanism that allowed some kind of a seal override on any externally referenced context document that includes the @sealed:true directive.
The problem is real (as I said on the call, we do something similar for Web Publication Manifests). But I am not sure what that would mean...
We could revive the approach, briefly mentioned at some point but not really retained, to be able to "seal" only specific terms or those terms that are explicitly mentioned. In the schema.org example, it would mean sealing the @id
value (and possibly other values as given in the schema.org in the current context file) but allow extending the term definitions like what @tcole3 has shown. The problem was that this goes against the approach in JSON-LD 1.0 (where redefinition is an all or nothing action). Specifying this properly may lead to a spaghetti specification (and implementation...)
Another, more pragmatic approach is to make it very clear that... if possible, you should not seal a context. To be more specific, make it very clear that sealing an under-specified context may lead major issues, and publishers shouldn't do that. Sealing should be reserved for very specific use cases, where the context is extremely well specified and it would be an issue if they were redefined.
Schema.org is such an under-specified context (intentionally so), i.e., it would create lots of issues if it was sealed (truth must be said, I do not think they expressed interest in this). This also means that we should refrain using schema.org in any of our examples around sealing (@pchampin, this may require a slight re-write of #119). I think the same is true for FOAF and Dublin Core, b.t.w. At this moment, the VC ontology might be the only one coming to my mind that does require this. (@azaroth42, @tcole3, I am not sure the annotation vocabulary should be sealed either, but I am not sure).
- We could revive the approach, briefly mentioned at some point but not really retained, to be able to "seal" only specific terms or those terms that are explicitly mentioned. In the schema.org example, it would mean sealing the
@id
value (and possibly other values as given in the schema.org in the current context file) but allow extending the term definitions like what @tcole3 has shown. The problem was that this goes against the approach in JSON-LD 1.0 (where redefinition is an all or nothing action). Specifying this properly may lead to a spaghetti specification (and implementation...)
We need to consider the primary use case for sealing terms/contexts, which is to allow naive JSON apps to be able to interpret values as defined in a spec; this includes how to treat string values, and if an object value should be treated as a list, a map, or whatever. Allowing these things (or anything, really) to be overridden on a term sort of by definition does not allow naive apps to be able to properly understand their values. The only possible exception would be to add @container: @set
to ensure that compaction always uses array notation, but that's a compaction use case, which does not relate to naive JSON apps. So, I don't see a reason for us to do this.
- Another, more pragmatic approach is to make it very clear that... if possible, you should not seal a context. To be more specific, make it very clear that sealing an under-specified context may lead major issues, and publishers shouldn't do that. Sealing should be reserved for very specific use cases, where the context is extremely well specified and it would be an issue if they were redefined.
Yes, absolutely; we should caution that this feature should be used judiciously, if at all.
I lean towards option 2. Sealing should only be used in specific use cases, and schema.org does not fit in those, I think.
On Sun 3 Feb 2019, 21:04 Gregg Kellogg <notifications@github.com wrote:
- We could revive the approach, briefly mentioned at some point but not really retained, to be able to "seal" only specific terms or those terms that are explicitly mentioned. In the schema.org example, it would mean sealing the @id value (and possibly other values as given in the schema.org in the current context file) but allow extending the term definitions like what @tcole3 https://github.com/tcole3 has shown. The problem was that this goes against the approach in JSON-LD 1.0 (where redefinition is an all or nothing action). Specifying this properly may lead to a spaghetti specification (and implementation...)
We need to consider the primary use case for sealing terms/contexts, which is to allow naive JSON apps to be able to interpret values as defined in a spec; this includes how to treat string values, and if an object value should be treated as a list, a map, or whatever. Allowing these things (or anything, really) to be overridden on a term sort of by definition does not allow naive apps to be able to properly understand their values. The only possible exception would be to add @container: @set to ensure that compaction always uses array notation, but that's a compaction use case, which does not relate to naive JSON apps. So, I don't see a reason for us to do this.
- Another, more pragmatic approach is to make it very clear that... if possible, you should not seal a context. To be more specific, make it very clear that sealing an under-specified context may lead major issues, and publishers shouldn't do that. Sealing should be reserved for very specific use cases, where the context is extremely well specified and it would be an issue if they were redefined.
Yes, absolutely; we should caution that this feature should be used judiciously, if at all.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/w3c/json-ld-syntax/issues/20#issuecomment-460083446, or mute the thread https://github.com/notifications/unsubscribe-auth/AASl5DXM2y0LdKUGCuFr0bJH9sUxZ8YXks5vJ0DagaJpZM4U-BsL .
Agreed. The risks associated with misinterpreting schema.org data seem very small in comparison with the risks of misinterpreting WoT or Verifiable Claims data.
This issue was discussed in a meeting.
RESOLVED: Adopt the following rules for sealing 1) If
@sealed:trueis encountered on a term definition in the active context, then attempts to redefine the term will fail and result in a warning. 2) If
@sealed:trueis encountered on a context, then all terms defined within the context should be treated as having
@sealed:truein their definition 3) If
@sealed:falseis encountered on a term definition in the active context, where the context has been sealed with
@sealed:true, then the sealing for that term is removed. {: #resolution1 .resolution}
RESOLVED: Close #87, as unnecessary given above rules. {: #resolution2 .resolution}
RESOLVED: Close #98, as
@context: nullclears context definitions {: #resolution3 .resolution}
RESOLVED: Close #98, as
@context: nullclears context definitions {: #resolution4 .resolution}
RESOLVED: if
@idis not present in a term definition, and there is no default vocabulary, but has an expansion to an absolute IRI in the active context, then the
@idof the new definition is taken from the active context (otherwise this is still an error) {: #resolution5 .resolution}
RESOLVED: Once previous is done, we can close #116 {: #resolution6 .resolution}
RESOLVED: We agree with the processing order per #61: scoped definition from property, then from type, then embedded. PR to update docs to come. {: #resolution7 .resolution}
This issue was discussed in a meeting.
RESOLVED: After discussion, we agree on no change to sealed contexts from yesterday {: #resolution1 .resolution}
A number of standards track specifications use JSON-LD for extensibility but intentionally place limitations on overriding the terms defined in a core context. For example:
https://www.w3.org/TR/activitystreams-core/#jsonld
https://w3c.github.io/vc-data-model/#extensibility
It seems like it would be a nice feature to allow enforcement of this desire by JSON-LD processors. Then authors could be assured that the interpretation of a context would be proper and properly implemented JSON-LD processors would throw errors if rules were violated.
In short, I propose we add a keyword with boolean value such as
"@sealed": true
(that could appear in contexts) to JSON-LD 1.1 that enables processors to enforce a desire to prevent defined terms from being redefined in subsequent contexts, but allows for new terms (aka extensions) to be defined.Original issue: Introduce concept of "sealed" contexts #656