@githonllc/avouch 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -34,6 +34,7 @@ Read in this order:
34
34
  |---|---|
35
35
  | `SPEC.md` | concepts (foundation / extension), fields, rules R1–R12, fact contract |
36
36
  | `ontology.schema.json` | JSON Schema: `$id` and `formatVersion`; shape only, no project values |
37
+ | `vocab.ttl` | RDF vocabulary (`ofv:`) for exporting an ontology as RDF; one term per schema field (`test/vocab.test.ts`) |
37
38
  | `src/contract.ts` | `SourceFacts`: the facts with their sources, and diagnostics |
38
39
  | `src/checker.ts` | `check(ontology, facts)` returns the violations |
39
40
  | `src/patch.ts` | JSON-pointer patch that the mutation tests use |
@@ -159,6 +160,8 @@ The secret is generated from a list kept in a private repository; maintainers ne
159
160
 
160
161
  The ontology file has `formatVersion: 1`. The schema `$id` is `https://w3id.org/avouch/v1/schema.json`. The version rules are in SPEC section 8.
161
162
 
163
+ The RDF vocabulary is `vocab.ttl`, namespace `https://w3id.org/avouch/v1/vocab#` (prefix `ofv:`), served at `https://avouch.dev/v1/vocab.ttl`. An RDF export of an ontology (for example the Turtle export of Avouch Studio) names each field with the term of the same name. The check does not read the vocabulary. A change that adds a schema field adds its term in the same change: `test/vocab.test.ts` fails on a field without a term, except for the top-level sections, expressions (exported as one JSON literal), the `properties` of an object type (OWL properties) and the `ref` of a value type (the class itself); each exclusion has its reason in the test.
164
+
162
165
  ## License
163
166
 
164
167
  Copyright 2026 Githon LLC. Licensed under the Apache License 2.0. See `LICENSE` and `NOTICE`. The next section gives the exception.
package/SPEC.md CHANGED
@@ -308,13 +308,13 @@ Types:
308
308
  | 3 | `expected` is `null` | `cannot_reconcile`, `expectation_missing` |
309
309
  | 4 | `snapshot` is `null` | `cannot_reconcile`, `snapshot_missing` |
310
310
  | 5 | `decide(ont, action, snapshot, scope, bindings, actor, now)` throws | `cannot_reconcile`, `evaluator_error`; `detail` is the error message |
311
- | 6 | `reported.result` is neither an invocation result (`INVOCATION_RESULTS`) nor the `result` of a decision row or of `otherwise` of this action | `cannot_reconcile`, `runtime_unmapped`; `detail` is `reported.result` |
311
+ | 6 | `reported.result` is `SCOPE_DENIED`, or is neither an invocation result (`INVOCATION_RESULTS`) nor the `result` of a decision row or of `otherwise` of this action | `cannot_reconcile`, `runtime_unmapped`; `detail` is `reported.result` |
312
312
  | 7 | the result is INDETERMINATE | `cannot_reconcile`, `indeterminate`; `detail` is its reason |
313
313
  | 8 | otherwise: `evaluator` is `externalResult` of the result without `param` (a domain result is `{result}`; `INVALID_BINDING` keeps `reason`) | `match` with `result = evaluator` when the three results are pairwise equal; else `mismatch` |
314
314
 
315
315
  Two `Reported` values are equal when `result` is equal and `reason` is equal (both absent counts as equal).
316
316
 
317
- A missing runtime result is never filled in from the decision table; neither is a missing expectation. The evaluator result is computed only to compare. Envelope results are not reconciled: the evaluator does not implement the envelope, and a replay does not recompute domain conditions, so a replay is not a new decision. An action without a decision table gives no domain result, so every reported result other than an invocation result is unmapped for it.
317
+ A missing runtime result is never filled in from the decision table; neither is a missing expectation. The evaluator result is computed only to compare. Envelope results are not reconciled: the evaluator does not implement the envelope, and a replay does not recompute domain conditions, so a replay is not a new decision. An action without a decision table gives no domain result, so every reported result other than `INVALID_BINDING` and `PERMISSION_DENIED` is unmapped for it (envelope results stop at step 1).
318
318
 
319
319
  Once an invocation is inside the domain path of an action with a decision table, the runtime must report the domain result explicitly. A coarse signal, such as the status of a receipt, must not stand in for it: a coarse value can share a name with the expected result and give a false match. `runtime_missing` (nothing reported) and `runtime_unmapped` (a value the action cannot give) record the two ways this evidence fails.
320
320
 
@@ -330,7 +330,7 @@ The physical type mapping is checked here: the profile supplies `decode`, which
330
330
 
331
331
  ### Existence is not revealed
332
332
 
333
- `SCOPE_DENIED` is internal. `externalResult` maps it and `INVALID_BINDING` `not_found` to one value, `{result: INVALID_BINDING, param, reason: not_found}`, so a caller cannot learn that an id exists in another tenant. Other reasons, such as `type`, are reported as they are.
333
+ `SCOPE_DENIED` is internal. `externalResult` maps it and `INVALID_BINDING` `not_found` to one value, `{result: INVALID_BINDING, param, reason: not_found}`, so a caller cannot learn that an id exists in another tenant. Other reasons, such as `type`, are reported as they are. A runtime must not report `SCOPE_DENIED`; `reconcile` gives `runtime_unmapped` for it.
334
334
 
335
335
  ### Known limit
336
336
 
package/dist/src/expr.js CHANGED
@@ -9,6 +9,7 @@ export const EXPR_NODES = [
9
9
  export const DISPOSITION_CLASSES = ["rejected", "recorded", "pending", "applied"];
10
10
  // The fixed invocation result set of the format. The first two belong to the idempotency envelope. A disposition id may
11
11
  // not be one of these names.
12
+ // Every invocation-layer result, SCOPE_DENIED included. SCOPE_DENIED is internal and never reported (SPEC section 9).
12
13
  export const INVOCATION_RESULTS = ["REPLAYED", "IDEMPOTENCY_CONFLICT", "INVALID_BINDING", "SCOPE_DENIED", "PERMISSION_DENIED"];
13
14
  export class ExprError extends Error {
14
15
  path;
@@ -50,4 +50,5 @@ export declare function projectSnapshot(ont: Stage1Ontology, stores: Readonly<Re
50
50
  snapshot: Snapshot;
51
51
  defects: TypeDefect[];
52
52
  };
53
+ export declare function domainResults(ont: Stage1Ontology, actionId: string): readonly string[];
53
54
  export declare function reconcile(ont: Stage1Ontology, cases: readonly RuntimeCase[]): ReconcileRow[];
@@ -35,12 +35,21 @@ export function projectSnapshot(ont, stores, decode) {
35
35
  const same = (a, b) => a.result === b.result && a.reason === b.reason;
36
36
  const ENVELOPE = ["REPLAYED", "IDEMPOTENCY_CONFLICT"];
37
37
  const INVOCATION = INVOCATION_RESULTS;
38
- // The results a runtime may report for an action: the invocation results and the results its decision table gives.
39
- function mapped(ont, action, result) {
40
- if (INVOCATION.includes(result))
41
- return true;
42
- const decision = own(ont.actionTypes, action)?.decision;
43
- return (decision?.rows ?? []).some((r) => r.result === result) || decision?.otherwise?.result === result;
38
+ // The domain results of an action: each distinct result of its decision rows, in row order, then of otherwise.
39
+ // An action without a decision table gives none. Names only; the class is ont.dispositions[name].class. For an ontology
40
+ // that passes the check, every name is a key of dispositions and none is an invocation result (R1).
41
+ export function domainResults(ont, actionId) {
42
+ const action = own(ont.actionTypes, actionId);
43
+ if (action === undefined)
44
+ throw new Error(`unknown action ${actionId}`);
45
+ const names = [];
46
+ for (const r of action.decision?.rows ?? [])
47
+ if (!names.includes(r.result))
48
+ names.push(r.result);
49
+ const o = action.decision?.otherwise;
50
+ if (o !== undefined && !names.includes(o.result))
51
+ names.push(o.result);
52
+ return names;
44
53
  }
45
54
  // One row per case, in input order. The evaluator result is computed only to compare: a missing runtime result or
46
55
  // expectation is reported as such, never filled in from the decision table. Envelope results are not decisions (the
@@ -67,7 +76,9 @@ export function reconcile(ont, cases) {
67
76
  catch (e) {
68
77
  return cannot("evaluator_error", e instanceof Error ? e.message : String(e));
69
78
  }
70
- if (!mapped(ont, c.action, reported.result))
79
+ // SCOPE_DENIED is internal (SPEC section 9, Existence is not revealed): never a reportable result.
80
+ const reportable = reported.result !== "SCOPE_DENIED" && (INVOCATION.includes(reported.result) || domainResults(ont, c.action).includes(reported.result));
81
+ if (!reportable)
71
82
  return cannot("runtime_unmapped", reported.result);
72
83
  if (d.layer === "indeterminate")
73
84
  return cannot("indeterminate", d.reason);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@githonllc/avouch",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -30,6 +30,7 @@
30
30
  "dist/src/",
31
31
  "dist/cli/",
32
32
  "ontology.schema.json",
33
+ "vocab.ttl",
33
34
  "SPEC.md",
34
35
  "docs/",
35
36
  "NOTICE"
package/vocab.ttl ADDED
@@ -0,0 +1,499 @@
1
+ @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
2
+ @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
3
+ @prefix owl: <http://www.w3.org/2002/07/owl#> .
4
+ @prefix ofv: <https://w3id.org/avouch/v1/vocab#> .
5
+
6
+ <https://w3id.org/avouch/v1/vocab> a owl:Ontology ;
7
+ rdfs:label "Avouch vocabulary"@en ;
8
+ rdfs:seeAlso <https://w3id.org/avouch/v1/schema.json> .
9
+
10
+ ofv:Context a rdfs:Class ;
11
+ rdfs:label "Context" ;
12
+ rdfs:comment "Exported from the YAML path contexts.<name>." ;
13
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
14
+
15
+ ofv:OutOfScopeObjectType a rdfs:Class ;
16
+ rdfs:label "OutOfScopeObjectType" ;
17
+ rdfs:comment "Exported from the YAML path outOfScopeObjectTypes.<name>." ;
18
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
19
+
20
+ ofv:DerivedProperty a rdfs:Class ;
21
+ rdfs:label "DerivedProperty" ;
22
+ rdfs:comment "Exported from the YAML path derivedProperties.<id>." ;
23
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
24
+
25
+ ofv:ActionType a rdfs:Class ;
26
+ rdfs:label "ActionType" ;
27
+ rdfs:comment "Exported from the YAML path actionTypes.<ID>." ;
28
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
29
+
30
+ ofv:index a rdf:Property ;
31
+ rdfs:label "index" ;
32
+ rdfs:comment "Position (from 0) of a record in its YAML list. YAML: conditions[], decision.rows[], transitions[], knownSourceGaps[], permission_rows_not_commands[]" ;
33
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
34
+
35
+ ofv:key a rdf:Property ;
36
+ rdfs:label "key" ;
37
+ rdfs:comment "Name of an entry in a YAML mapping. YAML: non_link_fields.<key>, edit_cites.<key>, link_effects.<key>, transitions[].bind.<key>" ;
38
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
39
+
40
+ ofv:name a rdf:Property ;
41
+ rdfs:label "name" ;
42
+ rdfs:comment "Name of a permission row that is not a command. YAML: permission_rows_not_commands[].name" ;
43
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
44
+
45
+ ofv:reason a rdf:Property ;
46
+ rdfs:label "reason" ;
47
+ rdfs:comment "Reason text. YAML: permission_rows_not_commands[].reason, outOfScopeObjectTypes.<name>, objectTypes.<name>.non_link_fields.<key>.reason" ;
48
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
49
+
50
+ ofv:cite a rdf:Property ;
51
+ rdfs:label "cite" ;
52
+ rdfs:comment "Source citation (a node with doc and quote). YAML: cite, in any record that has one, scope.cite, scope.global[].cite, scope.root.cite, dispositions.<ID>.cite, decision.order.cite, decision…next.cite, derivedProperties.<id>.cite, ….principals.cite, actionTypes.<ID>.idempotencyKey.cite" ;
53
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
54
+
55
+ ofv:doc a rdf:Property ;
56
+ rdfs:label "doc" ;
57
+ rdfs:comment "Source document reference. YAML: doc, in any record that has one; also cite.doc" ;
58
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
59
+
60
+ ofv:quote a rdf:Property ;
61
+ rdfs:label "quote" ;
62
+ rdfs:comment "Quoted source text. YAML: cite.quote" ;
63
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
64
+
65
+ ofv:id a rdf:Property ;
66
+ rdfs:label "id" ;
67
+ rdfs:comment "Identifier of a record. YAML: knownSourceGaps[].id, actionTypes.<ID>.conditions[].id" ;
68
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
69
+
70
+ ofv:rule a rdf:Property ;
71
+ rdfs:label "rule" ;
72
+ rdfs:comment "Rule code of a source gap. YAML: knownSourceGaps[].rule" ;
73
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
74
+
75
+ ofv:kind a rdf:Property ;
76
+ rdfs:label "kind" ;
77
+ rdfs:comment "Kind of a source gap. YAML: knownSourceGaps[].kind" ;
78
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
79
+
80
+ ofv:keys a rdf:Property ;
81
+ rdfs:label "keys" ;
82
+ rdfs:comment "Keys of a record (permission keys, or gap keys). YAML: knownSourceGaps[].keys, actionTypes.<ID>.permission.keys" ;
83
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
84
+
85
+ ofv:doc_line a rdf:Property ;
86
+ rdfs:label "doc_line" ;
87
+ rdfs:comment "Document line of a source gap. YAML: knownSourceGaps[].doc_line" ;
88
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
89
+
90
+ ofv:conflict a rdf:Property ;
91
+ rdfs:label "conflict" ;
92
+ rdfs:comment "Conflict text of a source gap. YAML: knownSourceGaps[].conflict" ;
93
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
94
+
95
+ ofv:proposed a rdf:Property ;
96
+ rdfs:label "proposed" ;
97
+ rdfs:comment "Proposed fix of a source gap. YAML: knownSourceGaps[].proposed" ;
98
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
99
+
100
+ ofv:description a rdf:Property ;
101
+ rdfs:label "description" ;
102
+ rdfs:comment "Label of a context: a literal substring of the source line that lists its objects. YAML: contexts.<name>" ;
103
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
104
+
105
+ ofv:infrastructureStores a rdf:Property ;
106
+ rdfs:label "infrastructureStores" ;
107
+ rdfs:comment "Infrastructure stores that are not object types. YAML: infrastructureStores[]" ;
108
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
109
+
110
+ ofv:permission_rows_not_commands a rdf:Property ;
111
+ rdfs:label "permission_rows_not_commands" ;
112
+ rdfs:comment "Permission rows that are not commands. YAML: permission_rows_not_commands[]" ;
113
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
114
+
115
+ ofv:knownSourceGaps a rdf:Property ;
116
+ rdfs:label "knownSourceGaps" ;
117
+ rdfs:comment "Known gaps in the source document. YAML: knownSourceGaps[]" ;
118
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
119
+
120
+ ofv:context a rdf:Property ;
121
+ rdfs:label "context" ;
122
+ rdfs:comment "Context of an object type, action type or create rule. YAML: objectTypes.<name>.context, actionTypes.<ID>.context, linkTypes[].create_rule.context" ;
123
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
124
+
125
+ ofv:datasource a rdf:Property ;
126
+ rdfs:label "datasource" ;
127
+ rdfs:comment "Store that holds the object. YAML: objectTypes.<name>.datasource" ;
128
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
129
+
130
+ ofv:non_link_fields a rdf:Property ;
131
+ rdfs:label "non_link_fields" ;
132
+ rdfs:comment "Fields that look like links but are not. YAML: objectTypes.<name>.non_link_fields" ;
133
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
134
+
135
+ ofv:stateMachines a rdf:Property ;
136
+ rdfs:label "stateMachines" ;
137
+ rdfs:comment "State machine of an object type. YAML: stateMachines.<name>" ;
138
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
139
+
140
+ ofv:initial a rdf:Property ;
141
+ rdfs:label "initial" ;
142
+ rdfs:comment "Initial state. YAML: stateMachines.<name>.initial" ;
143
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
144
+
145
+ ofv:terminal a rdf:Property ;
146
+ rdfs:label "terminal" ;
147
+ rdfs:comment "Terminal state. YAML: stateMachines.<name>.terminal[]" ;
148
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
149
+
150
+ ofv:transitions a rdf:Property ;
151
+ rdfs:label "transitions" ;
152
+ rdfs:comment "State transition. YAML: stateMachines.<name>.transitions[]" ;
153
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
154
+
155
+ ofv:from a rdf:Property ;
156
+ rdfs:label "from" ;
157
+ rdfs:comment "Source state of a transition. YAML: stateMachines.<name>.transitions[].from" ;
158
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
159
+
160
+ ofv:to a rdf:Property ;
161
+ rdfs:label "to" ;
162
+ rdfs:comment "Target state of a transition. YAML: stateMachines.<name>.transitions[].to" ;
163
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
164
+
165
+ ofv:by a rdf:Property ;
166
+ rdfs:label "by" ;
167
+ rdfs:comment "Action type that causes a transition. YAML: stateMachines.<name>.transitions[].by[]" ;
168
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
169
+
170
+ ofv:out_of_scope a rdf:Property ;
171
+ rdfs:label "out_of_scope" ;
172
+ rdfs:comment "Why no declared action performs the transition. YAML: stateMachines.<name>.transitions[].out_of_scope" ;
173
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
174
+
175
+ ofv:bind a rdf:Property ;
176
+ rdfs:label "bind" ;
177
+ rdfs:comment "Per-action evidence for a transition, keyed by action id. YAML: stateMachines.<name>.transitions[].bind.<ID>" ;
178
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
179
+
180
+ ofv:class a rdf:Property ;
181
+ rdfs:label "class" ;
182
+ rdfs:comment "State class of a property: canonical, derived, policy or unknown. YAML: objectTypes.<name>.properties.<p>.class" ;
183
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
184
+
185
+ ofv:canonical_values a rdf:Property ;
186
+ rdfs:label "canonical_values" ;
187
+ rdfs:comment "Values of a non-canonical property that the source explicitly marks as canonical. YAML: objectTypes.<name>.properties.<p>.canonical_values" ;
188
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
189
+
190
+ ofv:values a rdf:Property ;
191
+ rdfs:label "values" ;
192
+ rdfs:comment "Values of a list. YAML: canonical_values.values[], conditions[].reads[].values[]" ;
193
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
194
+
195
+ ofv:materializedFrom a rdf:Property ;
196
+ rdfs:label "materializedFrom" ;
197
+ rdfs:comment "The source requires this derived property to be stored in the same operation as its inputs. YAML: objectTypes.<name>.properties.<p>.materializedFrom" ;
198
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
199
+
200
+ ofv:reads a rdf:Property ;
201
+ rdfs:label "reads" ;
202
+ rdfs:comment "Properties read. YAML: materializedFrom.reads[], derivedProperties.<id>.reads[], conditions[].reads[]" ;
203
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
204
+
205
+ ofv:cites a rdf:Property ;
206
+ rdfs:label "cites" ;
207
+ rdfs:comment "Citations, each a node with ofv:cite. YAML: objectTypes.<name>.properties.<p>.materializedFrom.cites[], actionTypes.<ID>.conditions[].cites[], decision.rows[].cites[], decision.otherwise.cites[]" ;
208
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
209
+
210
+ ofv:cardinality a rdf:Property ;
211
+ rdfs:label "cardinality" ;
212
+ rdfs:comment "Cardinality text of a link type, kept as written. YAML: linkTypes[].cardinality" ;
213
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
214
+
215
+ ofv:via a rdf:Property ;
216
+ rdfs:label "via" ;
217
+ rdfs:comment "Foreign-key field on the from object or the link store name (linkTypes[].via); the mechanism of a cross-context write (crossContext.via). YAML: linkTypes[].via, actionTypes.<ID>.crossContext.via" ;
218
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
219
+
220
+ ofv:table a rdf:Property ;
221
+ rdfs:label "table" ;
222
+ rdfs:comment "The link's own store. YAML: linkTypes[].table" ;
223
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
224
+
225
+ ofv:create_rule a rdf:Property ;
226
+ rdfs:label "create_rule" ;
227
+ rdfs:comment "Who may establish the link. YAML: linkTypes[].create_rule" ;
228
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
229
+
230
+ ofv:with_creates a rdf:Property ;
231
+ rdfs:label "with_creates" ;
232
+ rdfs:comment "Objects the action must create in the same operation. YAML: linkTypes[].create_rule.with_creates[]" ;
233
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
234
+
235
+ ofv:exceptions a rdf:Property ;
236
+ rdfs:label "exceptions" ;
237
+ rdfs:comment "Exceptions to a create rule. YAML: linkTypes[].create_rule.exceptions" ;
238
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
239
+
240
+ ofv:commands a rdf:Property ;
241
+ rdfs:label "commands" ;
242
+ rdfs:comment "Action types that are exceptions to a create rule. YAML: linkTypes[].create_rule.exceptions.commands[]" ;
243
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
244
+
245
+ ofv:of a rdf:Property ;
246
+ rdfs:label "of" ;
247
+ rdfs:comment "Object a derived property is defined on. YAML: derivedProperties.<id>.of" ;
248
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
249
+
250
+ ofv:doc_term a rdf:Property ;
251
+ rdfs:label "doc_term" ;
252
+ rdfs:comment "Term used in the source document. YAML: derivedProperties.<id>.doc_term, actionTypes.<ID>.doc_term" ;
253
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
254
+
255
+ ofv:evidence a rdf:Property ;
256
+ rdfs:label "evidence" ;
257
+ rdfs:comment "Id of the evidence that implements the action. YAML: actionTypes.<ID>.evidence" ;
258
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
259
+
260
+ ofv:emits a rdf:Property ;
261
+ rdfs:label "emits" ;
262
+ rdfs:comment "Event types the action writes. YAML: actionTypes.<ID>.emits[]" ;
263
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
264
+
265
+ ofv:creates a rdf:Property ;
266
+ rdfs:label "creates" ;
267
+ rdfs:comment "Object types an action type creates. YAML: actionTypes.<ID>.creates[]" ;
268
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
269
+
270
+ ofv:deletes a rdf:Property ;
271
+ rdfs:label "deletes" ;
272
+ rdfs:comment "Object types whose rows an action type removes (a soft delete is an edits). YAML: actionTypes.<ID>.deletes[]" ;
273
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
274
+
275
+ ofv:edits a rdf:Property ;
276
+ rdfs:label "edits" ;
277
+ rdfs:comment "Properties an action type edits. YAML: actionTypes.<ID>.edits[]" ;
278
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
279
+
280
+ ofv:edit_cites a rdf:Property ;
281
+ rdfs:label "edit_cites" ;
282
+ rdfs:comment "Citations of edits. YAML: actionTypes.<ID>.edit_cites.<key>" ;
283
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
284
+
285
+ ofv:crossContext a rdf:Property ;
286
+ rdfs:label "crossContext" ;
287
+ rdfs:comment "Cross-context write of an action type. YAML: actionTypes.<ID>.crossContext" ;
288
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
289
+
290
+ ofv:permission a rdf:Property ;
291
+ rdfs:label "permission" ;
292
+ rdfs:comment "Permission of an action type: a string, or a node with keys. YAML: actionTypes.<ID>.permission" ;
293
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
294
+
295
+ ofv:conditional_keys a rdf:Property ;
296
+ rdfs:label "conditional_keys" ;
297
+ rdfs:comment "Permission keys needed only under a condition. YAML: actionTypes.<ID>.permission.conditional_keys[]" ;
298
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
299
+
300
+ ofv:none a rdf:Property ;
301
+ rdfs:label "none" ;
302
+ rdfs:comment "Why there is no key (permission), or why the link is not changed (link effect). YAML: actionTypes.<ID>.permission.none, actionTypes.<ID>.link_effects.<key>.none" ;
303
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
304
+
305
+ ofv:conditional_cite a rdf:Property ;
306
+ rdfs:label "conditional_cite" ;
307
+ rdfs:comment "Citation for the conditional keys. YAML: actionTypes.<ID>.permission.conditional_cite" ;
308
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
309
+
310
+ ofv:any_of a rdf:Property ;
311
+ rdfs:label "any_of" ;
312
+ rdfs:comment "At least 2 alternatives, each a keys form; the actor may run the action when its keys satisfy any one of them (OR). YAML: actionTypes.<ID>.permission.any_of" ;
313
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
314
+
315
+ ofv:parameters a rdf:Property ;
316
+ rdfs:label "parameters" ;
317
+ rdfs:comment "Parameters of an action type, the inputs it takes; each has a key and a cite. YAML: actionTypes.<ID>.parameters" ;
318
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
319
+
320
+ ofv:param a rdf:Property ;
321
+ rdfs:label "param" ;
322
+ rdfs:comment "Parameter named in a read, optionally with values. YAML: actionTypes.<ID>.conditions[].reads[].param" ;
323
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
324
+
325
+ ofv:actor a rdf:Property ;
326
+ rdfs:label "actor" ;
327
+ rdfs:comment "The caller read by a criterion: id or keys. YAML: actionTypes.<ID>.conditions[].reads[].actor" ;
328
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
329
+
330
+ ofv:submissionCriteria a rdf:Property ;
331
+ rdfs:label "submissionCriteria" ;
332
+ rdfs:comment "Renamed to conditions; exports no longer use it. YAML before the rename: actionTypes.<ID>.submissionCriteria[]" ;
333
+ owl:deprecated true ;
334
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
335
+
336
+ ofv:conditions a rdf:Property ;
337
+ rdfs:label "conditions" ;
338
+ rdfs:comment "Condition of an action type: a named claim, written as an expression or stated as not yet written. YAML: actionTypes.<ID>.conditions[]" ;
339
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
340
+
341
+ ofv:expr a rdf:Property ;
342
+ rdfs:label "expr" ;
343
+ rdfs:comment "Expression as one rdf:JSON literal (object keys sorted, no white space), not as triples. YAML: actionTypes.<ID>.conditions[].expr, derivedProperties.<id>.expr" ;
344
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
345
+
346
+ ofv:prop a rdf:Property ;
347
+ rdfs:label "prop" ;
348
+ rdfs:comment "Property named in a read with values. YAML: actionTypes.<ID>.conditions[].reads[].prop" ;
349
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
350
+
351
+ ofv:reads_unspecified a rdf:Property ;
352
+ rdfs:label "reads_unspecified" ;
353
+ rdfs:comment "Statement that the reads are not specified. YAML: actionTypes.<ID>.conditions[].reads_unspecified" ;
354
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
355
+
356
+ ofv:scenarios a rdf:Property ;
357
+ rdfs:label "scenarios" ;
358
+ rdfs:comment "Scenario ids. YAML: conditions[].scenarios[], link_effects.<key>.scenarios[]" ;
359
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
360
+
361
+ ofv:link_effects a rdf:Property ;
362
+ rdfs:label "link_effects" ;
363
+ rdfs:comment "Effect of an action type on a link type. YAML: actionTypes.<ID>.link_effects" ;
364
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
365
+
366
+ ofv:effect a rdf:Property ;
367
+ rdfs:label "effect" ;
368
+ rdfs:comment "Text of a link effect. YAML: actionTypes.<ID>.link_effects.<key>.effect" ;
369
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
370
+
371
+ ofv:unspecified a rdf:Property ;
372
+ rdfs:label "unspecified" ;
373
+ rdfs:comment "Statement that something is not specified. YAML: actionTypes.<ID>.link_effects.<key>.unspecified, actionTypes.<ID>.crossContext.unspecified, actionTypes.<ID>.conditions[].unspecified, decision.rows[].next.unspecified, decision.otherwise.next.unspecified" ;
374
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
375
+
376
+ ofv:Disposition a rdfs:Class ;
377
+ rdfs:label "Disposition" ;
378
+ rdfs:comment "A result that a decision table can give. Exported from the YAML path dispositions.<ID>." ;
379
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
380
+
381
+ ofv:dispositionClass a rdf:Property ;
382
+ rdfs:label "dispositionClass" ;
383
+ rdfs:comment "Class of a disposition: rejected, recorded, pending or applied. YAML: dispositions.<ID>.class" ;
384
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
385
+
386
+ ofv:decision a rdf:Property ;
387
+ rdfs:label "decision" ;
388
+ rdfs:comment "Decision table of an action type. YAML: actionTypes.<ID>.decision" ;
389
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
390
+
391
+ ofv:hitPolicy a rdf:Property ;
392
+ rdfs:label "hitPolicy" ;
393
+ rdfs:comment "Hit policy of a decision table; v1 has only first (top to bottom, first match). YAML: actionTypes.<ID>.decision.hitPolicy" ;
394
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
395
+
396
+ ofv:order a rdf:Property ;
397
+ rdfs:label "order" ;
398
+ rdfs:comment "Citation for the row order of a decision table. YAML: actionTypes.<ID>.decision.order" ;
399
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
400
+
401
+ ofv:rows a rdf:Property ;
402
+ rdfs:label "rows" ;
403
+ rdfs:comment "Row of a decision table, with ofv:index. YAML: actionTypes.<ID>.decision.rows[]" ;
404
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
405
+
406
+ ofv:when a rdf:Property ;
407
+ rdfs:label "when" ;
408
+ rdfs:comment "Test of a row: a node with ofv:passes or ofv:fails. YAML: actionTypes.<ID>.decision.rows[].when" ;
409
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
410
+
411
+ ofv:passes a rdf:Property ;
412
+ rdfs:label "passes" ;
413
+ rdfs:comment "Id of a condition that must evaluate to T. YAML: actionTypes.<ID>.decision.rows[].when.passes" ;
414
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
415
+
416
+ ofv:fails a rdf:Property ;
417
+ rdfs:label "fails" ;
418
+ rdfs:comment "Id of a condition that does not evaluate to T (it is F or U). It is not a negation. YAML: actionTypes.<ID>.decision.rows[].when.fails" ;
419
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
420
+
421
+ ofv:result a rdf:Property ;
422
+ rdfs:label "result" ;
423
+ rdfs:comment "Disposition that a row gives: an ofv:Disposition, or a literal when the id is not declared. YAML: actionTypes.<ID>.decision.rows[].result, actionTypes.<ID>.decision.otherwise.result" ;
424
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
425
+
426
+ ofv:otherwise a rdf:Property ;
427
+ rdfs:label "otherwise" ;
428
+ rdfs:comment "Last row of a decision table; it gives the result when no row matches. YAML: actionTypes.<ID>.decision.otherwise" ;
429
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
430
+
431
+ ofv:next a rdf:Property ;
432
+ rdfs:label "next" ;
433
+ rdfs:comment "What follows a pending result. YAML: actionTypes.<ID>.decision.rows[].next, actionTypes.<ID>.decision.otherwise.next" ;
434
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
435
+
436
+ ofv:actions a rdf:Property ;
437
+ rdfs:label "actions" ;
438
+ rdfs:comment "Action type of this system that follows. YAML: decision.rows[].next.actions[], decision.otherwise.next.actions[]" ;
439
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
440
+
441
+ ofv:external a rdf:Property ;
442
+ rdfs:label "external" ;
443
+ rdfs:comment "Step outside this system that follows. YAML: decision.rows[].next.external, decision.otherwise.next.external" ;
444
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
445
+
446
+ ofv:scope a rdf:Property ;
447
+ rdfs:label "scope" ;
448
+ rdfs:comment "Tenant scope of the ontology. YAML: scope" ;
449
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
450
+
451
+ ofv:scopeBy a rdf:Property ;
452
+ rdfs:label "scopeBy" ;
453
+ rdfs:comment "Name of the field that holds the tenant. YAML: scope.by" ;
454
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
455
+
456
+ ofv:global a rdf:Property ;
457
+ rdfs:label "global" ;
458
+ rdfs:comment "Object type that all tenants share, with its citation. YAML: scope.global[]" ;
459
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
460
+
461
+ ofv:root a rdf:Property ;
462
+ rdfs:label "root" ;
463
+ rdfs:comment "Object type that is the tenant itself, with its citation. YAML: scope.root" ;
464
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
465
+
466
+ ofv:type a rdf:Property ;
467
+ rdfs:label "type" ;
468
+ rdfs:comment "A type. For a value type: a literal (enum, timestamp, duration, date, timezone, id, integer or boolean), the class whose ids the value holds, or a node with ofv:set. For a scope entry: the class of the entry. YAML: objectTypes.<name>.properties.<p>.type, actionTypes.<ID>.parameters.<n>.type, derivedProperties.<id>.type, scope.global[].type, scope.root.type" ;
469
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
470
+
471
+ ofv:set a rdf:Property ;
472
+ rdfs:label "set" ;
473
+ rdfs:comment "Element type of a set type, written as for ofv:type; string is allowed here only. YAML: ….type.set" ;
474
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
475
+
476
+ ofv:optional a rdf:Property ;
477
+ rdfs:label "optional" ;
478
+ rdfs:comment "The caller may leave the parameter out; it is then null. YAML: actionTypes.<ID>.parameters.<n>.optional" ;
479
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
480
+
481
+ ofv:principals a rdf:Property ;
482
+ rdfs:label "principals" ;
483
+ rdfs:comment "Actor kinds that one permission alternative admits, with its own citation; an actor of another kind is denied. YAML: actionTypes.<ID>.permission.principals, actionTypes.<ID>.permission.any_of[].principals" ;
484
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
485
+
486
+ ofv:kinds a rdf:Property ;
487
+ rdfs:label "kinds" ;
488
+ rdfs:comment "One actor kind. YAML: actionTypes.<ID>.permission.principals.kinds[], actionTypes.<ID>.permission.any_of[].principals.kinds[]" ;
489
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
490
+
491
+ ofv:idempotencyKey a rdf:Property ;
492
+ rdfs:label "idempotencyKey" ;
493
+ rdfs:comment "Declaration of whether the caller must supply an idempotency key for this action type, with its citation. Absent means unspecified, not false; never derived from the action's effects. YAML: actionTypes.<ID>.idempotencyKey" ;
494
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .
495
+
496
+ ofv:required a rdf:Property ;
497
+ rdfs:label "required" ;
498
+ rdfs:comment "Whether the caller must supply an idempotency key; true and false are both explicit, cited claims. YAML: actionTypes.<ID>.idempotencyKey.required" ;
499
+ rdfs:isDefinedBy <https://w3id.org/avouch/v1/vocab> .