@chronicle.app/schema 0.4.0 → 0.5.0

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
@@ -115,6 +115,16 @@ typing; use validators at runtime to enforce identity requirements.
115
115
  - A datatype is an `rdfs:Datatype` defined over XSD. Each accepts the plain
116
116
  strings that Chronicle JSON becomes in JSON-LD as well as typed values, such
117
117
  as an `xsd:dateTime` for an instant.
118
+ - A property can name its inverse with `:inverseName`, such as `hasPart` on
119
+ `:isPartOf`. A record can give the relation under either name, so a whole
120
+ can list its parts, and only the forward edge is stored. The generated
121
+ `INVERSE_PROPERTIES` maps each inverse name to its forward property.
122
+ - A number property can say what form its values take with `:metric`. A
123
+ `gauge` is a level or a rate, such as a heart rate, and combines as a mean,
124
+ minimum, or maximum. A `sum` is an amount, such as a number of steps, and
125
+ adds up. A metric's `:unit` is the one unit all its values are in, as a UCUM
126
+ code such as `/min`. The generated `METRIC_PROPERTIES` gives each metric's
127
+ form and unit.
118
128
  - A SHACL property shape after a property holds its record rules. `sh:maxCount 1`
119
129
  makes it take one value. A shape with `sh:targetClass` and `sh:minCount 1`
120
130
  makes it required on that class.
@@ -125,7 +135,8 @@ The generator turns the ontology into TypeScript types and Zod validators. It
125
135
  reads terms through `scripts/terms.js`, which the schema site also uses. It
126
136
  handles inheritance, including a class with two parents, domains and ranges,
127
137
  and SHACL counts, and it fails for cyclic inheritance, undeclared referenced
128
- classes, or a property with two domains or ranges. The package has no
138
+ classes, a property with two domains or ranges, or a metric that isn't a
139
+ gauge or a sum of numbers in one unit. The package has no
129
140
  persistence metadata, derived effects, or runtime filesystem parser.
130
141
  Generated runtime code depends only on Zod; the TTL is also included in the package.
131
142
 
@@ -156,8 +167,10 @@ documentation under the same release path. Published snapshots must never be
156
167
  overwritten or removed by later deployments. The unversioned `/chronicle.ttl`
157
168
  and term pages serve `main`, so `main` holds only vocabulary that is ready to
158
169
  publish: work on new terms in a branch until it is ready. Any change to
159
- `chronicle.ttl` after a release must raise `owl:versionInfo`;
160
- `npm run schema:check` enforces this against the latest release tag. See [Preparing a release](../../RELEASING.md) for the
170
+ `chronicle.ttl` after a release must raise `owl:versionInfo`. While the
171
+ vocabulary is in flux, `npm run schema:check` doesn't check this, so run
172
+ `npm run version:check` before a release to compare against the latest release
173
+ tag. See [Preparing a release](../../RELEASING.md) for the
161
174
  release procedure.
162
175
 
163
176
  The vocabulary is intentionally small. Add terms only when a plugin needs them;
package/chronicle.ttl CHANGED
@@ -14,11 +14,33 @@
14
14
  @prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
15
15
 
16
16
  : a owl:Ontology;
17
- owl:versionInfo "0.3.0" .
17
+ owl:versionInfo "0.4.0" .
18
18
 
19
- # Annotations on properties, for tools rather than records.
19
+ # Annotations on properties, for tools rather than records. :inverseName on
20
+ # a property names its inverse: a record can give the relation under either
21
+ # name, and a store keeps only the forward property. :assertedBy and
22
+ # :retractedBy on a standing relation name the actions that start and end it,
23
+ # and :runPredicate names the relation as those actions' history.
24
+ #
25
+ # :metric on a number property says what form its values take, and so how
26
+ # its values over a time combine. A "gauge" is a level or a rate, such as a
27
+ # heart rate, and combines as a mean, minimum, or maximum. A "sum" is an
28
+ # amount, such as a number of steps, and adds up. Each value is for its
29
+ # action's time: its :timestamp, or its :startTime to its :endTime. A
30
+ # metric's :unit is the one unit all its values are in, as a UCUM code such
31
+ # as `/min`, so values from any source can be compared. Values of two
32
+ # properties can't be, even in the same unit.
20
33
  :abstract a owl:AnnotationProperty .
21
34
  :propagatesEncounter a owl:AnnotationProperty .
35
+ :metric a owl:AnnotationProperty .
36
+ :unit a owl:AnnotationProperty .
37
+ :inverseName a owl:AnnotationProperty .
38
+ :assertedBy a owl:AnnotationProperty .
39
+ :retractedBy a owl:AnnotationProperty .
40
+ :runPredicate a owl:AnnotationProperty .
41
+
42
+ # Derived query vocabulary. These are not rdf:Property payload fields.
43
+ :DerivedProperty a rdfs:Class .
22
44
 
23
45
  :Base a owl:Class;
24
46
  rdfs:comment "Anything a source describes, either an :Entity or an :Action. Each one has an identity, so other records can refer to it.";
@@ -65,7 +87,7 @@
65
87
  skos:exactMatch schemaorg:url .
66
88
  [] a sh:PropertyShape; sh:path :url; sh:targetSubjectsOf :url; sh:maxCount 1 .
67
89
  :object a owl:ObjectProperty;
68
- rdfs:comment "The entity an action was carried out on, such as the article read, the message sent, or the place visited. For a movement, such as a :TravelAction, the :object is where it began.";
90
+ rdfs:comment "The entity an action was carried out on, such as the article read, the photo shared, or the place visited. For a movement, such as a :TravelAction, the :object is where it began.";
69
91
  rdfs:domain :Action;
70
92
  rdfs:range :Entity;
71
93
  skos:exactMatch schemaorg:object .
@@ -147,10 +169,19 @@
147
169
  rdfs:range :Text .
148
170
  [] a sh:PropertyShape; sh:path :handle; sh:targetSubjectsOf :handle; sh:maxCount 1 .
149
171
  :isPartOf a owl:ObjectProperty;
150
- rdfs:comment "A whole that the entity is part of, such as a task's project or the page an excerpt comes from.";
172
+ rdfs:comment "A whole that the entity is part of, such as a task's project, the page an excerpt comes from, or the transaction a posting belongs to. Seen from the whole, its parts are its `hasPart` values.";
173
+ :inverseName "hasPart";
151
174
  rdfs:domain :Entity;
152
175
  rdfs:range :Entity;
153
176
  skos:exactMatch schemaorg:isPartOf .
177
+ :isStageOf a owl:ObjectProperty;
178
+ rdfs:comment "The session that this session is a stage of, such as the night that a stretch of deep sleep is a stage of. A stage is part of how the whole went and does not happen apart from it. A whole's stages of the same type do not overlap, though together they need not cover it. Seen from the whole, its stages are its `hasStage` values.";
179
+ :inverseName "hasStage";
180
+ rdfs:subPropertyOf :isPartOf;
181
+ rdfs:domain :Session;
182
+ rdfs:range :Session;
183
+ skos:broadMatch schemaorg:isPartOf .
184
+ [] a sh:PropertyShape; sh:path :isStageOf; sh:targetSubjectsOf :isStageOf; sh:maxCount 1 .
154
185
  :about a owl:ObjectProperty;
155
186
  rdfs:comment "What the entity is about, such as a topic or a tag.";
156
187
  rdfs:domain :Entity;
@@ -188,14 +219,14 @@
188
219
  skos:broadMatch schemaorg:Message .
189
220
  :MessageAction a owl:Class;
190
221
  rdfs:subClassOf :Action;
191
- rdfs:comment "The agent sent a message. The :object is the message." .
222
+ rdfs:comment "The agent sent a message. Its :result is the :Message." .
192
223
  :MediaObject a owl:Class;
193
224
  rdfs:subClassOf :CreativeWork;
194
225
  rdfs:comment "A media file, such as an image, an audio recording, a video, or a document. Its :contentPath or :url locates the file, and its :mimeType gives its format.";
195
226
  skos:broadMatch schemaorg:MediaObject .
196
227
  :ImageObject a owl:Class;
197
228
  rdfs:subClassOf :MediaObject;
198
- rdfs:comment "An image, such as a photograph, a screenshot, or an image attachment.";
229
+ rdfs:comment "An image file, such as a photo's file, a screenshot, or an image attachment.";
199
230
  skos:broadMatch schemaorg:ImageObject .
200
231
  :AudioObject a owl:Class;
201
232
  rdfs:subClassOf :MediaObject;
@@ -203,22 +234,35 @@
203
234
  skos:broadMatch schemaorg:AudioObject .
204
235
  :VideoObject a owl:Class;
205
236
  rdfs:subClassOf :MediaObject;
206
- rdfs:comment "A video, such as a recorded clip or a video attachment. It can include sound.";
237
+ rdfs:comment "A video file, such as a recorded clip or a video attachment. It can include sound.";
207
238
  skos:broadMatch schemaorg:VideoObject .
239
+ :StillImage a owl:Class;
240
+ rdfs:subClassOf :CreativeWork;
241
+ rdfs:comment "A still picture as a work, such as a photograph or a screenshot: what it shows, apart from the files that hold it. Each file is one of its :rendition values, usually an :ImageObject. A picture captured with a moment of motion also has a short :VideoObject.";
242
+ skos:narrowMatch schemaorg:Photograph .
243
+ :MovingImage a owl:Class;
244
+ rdfs:subClassOf :CreativeWork;
245
+ rdfs:comment "A video as a work, such as one recorded with a camera or of a screen: what it shows, apart from the files that hold it. Each file is one of its :rendition values, a :VideoObject." .
246
+ :rendition a owl:ObjectProperty;
247
+ rdfs:comment "A file that holds the work, such as a picture's image file, a video's video file, or an episode's audio file. A work can have several, such as a picture's image and the short video captured with it, or the same picture in two formats. Seen from the file, the work is its `renditionOf` value.";
248
+ :inverseName "renditionOf";
249
+ rdfs:domain :CreativeWork;
250
+ rdfs:range :MediaObject;
251
+ skos:exactMatch schemaorg:encoding .
208
252
  :DocumentObject a owl:Class;
209
253
  rdfs:subClassOf :MediaObject;
210
254
  rdfs:comment "A document file, such as a PDF, a text file, or a document attachment." .
211
255
  :recipient a owl:ObjectProperty;
212
- rdfs:comment "An agent the message or call was directed to, such as each other participant in a group conversation.";
256
+ rdfs:comment "An agent the message, call, or transaction was directed to, such as each other participant in a group conversation or the merchant that was paid.";
213
257
  rdfs:subPropertyOf :involvement;
214
- rdfs:domain [ a owl:Class; owl:unionOf ( :Message :CallSession ) ];
258
+ rdfs:domain [ a owl:Class; owl:unionOf ( :Message :CallSession :FinancialTransaction ) ];
215
259
  rdfs:range :Agent;
216
260
  skos:exactMatch schemaorg:recipient .
217
261
  :contains a owl:ObjectProperty;
218
- rdfs:comment "A media file the entity is made of, such as the photo in a :Post, the images and videos in a carousel, or an attachment to a :Message. Each one has its most specific type, such as :ImageObject.";
262
+ rdfs:comment "A media file that is part of the entity, such as an attachment to a :Message, the photo in a :Post, or the images and videos in a carousel. Each one has its most specific type, such as :ImageObject.";
219
263
  rdfs:domain :Entity;
220
264
  rdfs:range :MediaObject;
221
- skos:closeMatch schemaorg:associatedMedia .
265
+ skos:broadMatch schemaorg:hasPart .
222
266
  :contentPath a owl:DatatypeProperty;
223
267
  rdfs:comment "The absolute filesystem path of the local file that holds the media.";
224
268
  rdfs:domain :MediaObject;
@@ -231,6 +275,12 @@
231
275
  rdfs:range :Text;
232
276
  skos:closeMatch schemaorg:encodingFormat .
233
277
  [] a sh:PropertyShape; sh:path :mimeType; sh:targetSubjectsOf :mimeType; sh:maxCount 1 .
278
+ :contentSize a owl:DatatypeProperty;
279
+ rdfs:comment "The size of the file, in bytes.";
280
+ rdfs:domain :MediaObject;
281
+ rdfs:range :Number;
282
+ skos:closeMatch schemaorg:contentSize .
283
+ [] a sh:PropertyShape; sh:path :contentSize; sh:targetSubjectsOf :contentSize; sh:maxCount 1 .
234
284
  :transcript a owl:DatatypeProperty;
235
285
  rdfs:comment "The words spoken in a recording or an episode, written out, such as a voice memo's transcript, a podcast episode's transcript, or a video's captions. It is plain text with no timings. It belongs to the work rather than to one of its files, so a podcast episode's transcript is the episode's, not its audio file's. Spoken words are a :transcript, not a :body.";
236
286
  rdfs:domain [ a owl:Class; owl:unionOf ( :AudioObject :VideoObject :PodcastEpisode ) ];
@@ -277,9 +327,9 @@
277
327
  rdfs:range :Realm .
278
328
  [] a sh:PropertyShape; sh:path :inRealm; sh:targetSubjectsOf :inRealm; sh:maxCount 1 .
279
329
  :inAccount a owl:ObjectProperty;
280
- rdfs:comment "The agent whose account holds the entity, as that account's service knows them, such as the owner of an email account a message was delivered to. An entity held in several accounts is :inAccount each. Identifiers an account issues are unique within it.";
330
+ rdfs:comment "The account that holds the entity. For an account with a service, it is the agent whose account it is, as that service knows them, such as the owner of an email account a message was delivered to. For a :FinancialAccount, it is the account itself, such as the one a :FinancialPosting is on or a :PaymentCard draws on. An entity held in several accounts is :inAccount each. Identifiers an account issues are unique within it.";
281
331
  rdfs:domain :Entity;
282
- rdfs:range :Agent .
332
+ rdfs:range [ a owl:Class; owl:unionOf ( :Agent :FinancialAccount ) ] .
283
333
 
284
334
  :ConsumeAction a owl:Class;
285
335
  rdfs:comment "The agent took in the :object, such as by reading, watching, listening to, eating, or drinking it. The subclasses name how. A :ConsumeAction of no subclass records consumption in progress with no known start.";
@@ -296,6 +346,8 @@
296
346
  owl:equivalentClass [ a rdfs:Datatype; owl:unionOf ( xsd:decimal
297
347
  [ a rdfs:Datatype; owl:onDatatype xsd:double; owl:withRestrictions ( [ xsd:minExclusive "-INF"^^xsd:double ] [ xsd:maxExclusive "INF"^^xsd:double ] ) ] ) ];
298
348
  skos:broadMatch schemaorg:Number .
349
+ :JSONObject a rdfs:Datatype;
350
+ rdfs:comment "A JSON object whose values are text or numbers, such as `{\"FNumber\": 1.8, \"LensModel\": \"EF50mm f/1.8 STM\"}`. The property that takes it says what its keys are. Not allowed: an array (`[1.8]`), a nested object (`{\"Lens\": {\"Model\": \"EF50mm\"}}`), or `true`, `false`, or `null` as a value." .
299
351
  :startTime a owl:DatatypeProperty;
300
352
  rdfs:comment "When the action started. A date gives the start at that date's precision.";
301
353
  rdfs:domain :Action;
@@ -309,7 +361,8 @@
309
361
  skos:exactMatch schemaorg:endTime .
310
362
  [] a sh:PropertyShape; sh:path :endTime; sh:targetSubjectsOf :endTime; sh:maxCount 1 .
311
363
  :result a owl:ObjectProperty;
312
- rdfs:comment "What the action produced, such as a work or a session.";
364
+ rdfs:comment "What the action produced, such as a work or a session. Seen from what it produced, the action is its `resultOf` value.";
365
+ :inverseName "resultOf";
313
366
  rdfs:domain :Action;
314
367
  rdfs:range :Entity;
315
368
  skos:exactMatch schemaorg:result .
@@ -375,7 +428,7 @@
375
428
  skos:broadMatch schemaorg:TravelAction .
376
429
  :Journey a owl:Class;
377
430
  rdfs:comment "A recorded stretch of travel, with its :travelMode, its :distance, and its route as its :path. It is the :result of a :TravelAction, which gives its start and end.";
378
- rdfs:subClassOf :Entity .
431
+ rdfs:subClassOf :Session .
379
432
  :travelMode a owl:DatatypeProperty;
380
433
  rdfs:comment "How the journey was made, such as `walking`, `cycling`, or `metro`.";
381
434
  rdfs:domain :Journey;
@@ -462,11 +515,24 @@
462
515
  :CallAction a owl:Class;
463
516
  rdfs:comment "The agent made a phone or video call. Its :result is the :CallSession.";
464
517
  rdfs:subClassOf :CommunicateAction .
518
+ :ShareAction a owl:Class;
519
+ rdfs:comment "The agent shared the :object with others, such as by sending a photo in a conversation.";
520
+ rdfs:subClassOf :CommunicateAction;
521
+ skos:exactMatch schemaorg:ShareAction .
465
522
  :Session a owl:Class;
466
- rdfs:comment "A described period of the subject's activity, such as a block of app use, a manually logged block of time, or a call. Unlike an :Event, it is not a named happening. Its :scheduledStart and :scheduledEnd give a planned period. The action that records it gives when it actually happened.";
523
+ rdfs:comment "A period of one person's activity or experience, such as a night's sleep, a logged block of work, a trip across town, or their time on a call. The action that records it gives when it actually happened. Others who took part have sessions of their own. Something they shared, such as a concert or a meeting, is an :Event that each session :isPartOf. Its :scheduledStart and :scheduledEnd give a planned period.";
467
524
  rdfs:subClassOf :Entity .
468
525
  :CallSession a owl:Class;
469
- rdfs:comment "A phone or video call, as a period of time. It is the :result of a :CallAction. Its :recipient is who received the call. A group call :isPartOf a :Channel whose :member values are the participants. A missed call has zero length.";
526
+ rdfs:comment "One person's time on a phone or video call. It is the :result of a :CallAction. Its :recipient is who received the call. A group call's session :isPartOf a :Channel whose :member values are the participants. A missed call has zero length.";
527
+ rdfs:subClassOf :Session .
528
+ :SleepAction a owl:Class;
529
+ rdfs:comment "The agent slept from :startTime to :endTime, such as for a night or a nap, including any brief wakings. Its :result is the :SleepSession.";
530
+ rdfs:subClassOf :ExperienceAction .
531
+ :SleepSession a owl:Class;
532
+ rdfs:comment "A period of sleep, such as a night or a nap. It is the :result of a :SleepAction, which gives its start and end. Each tracked stage of it is a :SleepStage that :isStageOf it.";
533
+ rdfs:subClassOf :Session .
534
+ :SleepStage a owl:Class;
535
+ rdfs:comment "A stretch of one stage of sleep, such as deep sleep, that :isStageOf a :SleepSession. It is the :result of an :ExperienceAction, which gives its start and end. Its :category is the stage: `awake`, `light`, `deep`, `REM`, or `asleep` when the stage is not known. Not allowed: another name for one of these, such as `core` for light sleep.";
470
536
  rdfs:subClassOf :Session .
471
537
  :EatAction a owl:Class;
472
538
  rdfs:comment "The agent ate the :object, a :Meal. Where they ate is the action's :location.";
@@ -479,12 +545,113 @@
479
545
  :Meal a owl:Class;
480
546
  rdfs:comment "A meal or snack that the subject ate. Its :category is its slot, such as breakfast, lunch, or dinner.";
481
547
  rdfs:subClassOf :Entity .
548
+
549
+ :MeasureAction a owl:Class;
550
+ rdfs:comment "The agent took a measurement of the :object, such as a person's heart rate or weight. Each value measured is a property of the :object, such as its :heartRate. A value measured over a period, such as a daily resting heart rate or the steps taken in a few minutes, has a :startTime and :endTime.";
551
+ rdfs:subClassOf :Action .
552
+ :heartRate a owl:DatatypeProperty;
553
+ :metric "gauge";
554
+ :unit "/min";
555
+ rdfs:comment "The heart rate, in beats per minute.";
556
+ rdfs:domain :Person;
557
+ rdfs:range :Number .
558
+ [] a sh:PropertyShape; sh:path :heartRate; sh:targetSubjectsOf :heartRate; sh:maxCount 1 .
559
+ :restingHeartRate a owl:DatatypeProperty;
560
+ :metric "gauge";
561
+ :unit "/min";
562
+ rdfs:comment "The heart rate at rest, in beats per minute.";
563
+ rdfs:domain :Person;
564
+ rdfs:range :Number .
565
+ [] a sh:PropertyShape; sh:path :restingHeartRate; sh:targetSubjectsOf :restingHeartRate; sh:maxCount 1 .
566
+ :walkingHeartRate a owl:DatatypeProperty;
567
+ :metric "gauge";
568
+ :unit "/min";
569
+ rdfs:comment "The average heart rate while walking, in beats per minute.";
570
+ rdfs:domain :Person;
571
+ rdfs:range :Number .
572
+ [] a sh:PropertyShape; sh:path :walkingHeartRate; sh:targetSubjectsOf :walkingHeartRate; sh:maxCount 1 .
573
+ :heartRateVariabilitySdnn a owl:DatatypeProperty;
574
+ :metric "gauge";
575
+ :unit "ms";
576
+ rdfs:comment "The variation in time between heartbeats as SDNN: the standard deviation of the intervals between beats over the measurement's period, in milliseconds. It grows with the length of the period, so values over periods of different lengths don't compare. Other measures of the variation, such as RMSSD, differ from it.";
577
+ rdfs:domain :Person;
578
+ rdfs:range :Number .
579
+ [] a sh:PropertyShape; sh:path :heartRateVariabilitySdnn; sh:targetSubjectsOf :heartRateVariabilitySdnn; sh:maxCount 1 .
580
+ :heartRateRecovery a owl:DatatypeProperty;
581
+ :metric "gauge";
582
+ :unit "/min";
583
+ rdfs:comment "How far the heart rate fell in the minute after exercise, in beats per minute.";
584
+ rdfs:domain :Person;
585
+ rdfs:range :Number .
586
+ [] a sh:PropertyShape; sh:path :heartRateRecovery; sh:targetSubjectsOf :heartRateRecovery; sh:maxCount 1 .
587
+ :heartRhythm a owl:DatatypeProperty;
588
+ rdfs:comment "The rhythm of the heart, as an electrocardiogram classifies it, such as `sinus rhythm` or `atrial fibrillation`.";
589
+ rdfs:domain :Person;
590
+ rdfs:range :Text .
591
+ [] a sh:PropertyShape; sh:path :heartRhythm; sh:targetSubjectsOf :heartRhythm; sh:maxCount 1 .
592
+ :respiratoryRate a owl:DatatypeProperty;
593
+ :metric "gauge";
594
+ :unit "/min";
595
+ rdfs:comment "The breathing rate, in breaths per minute.";
596
+ rdfs:domain :Person;
597
+ rdfs:range :Number .
598
+ [] a sh:PropertyShape; sh:path :respiratoryRate; sh:targetSubjectsOf :respiratoryRate; sh:maxCount 1 .
599
+ :oxygenSaturation a owl:DatatypeProperty;
600
+ :metric "gauge";
601
+ :unit "1";
602
+ rdfs:comment "The fraction of hemoglobin in the blood that carries oxygen, from `0` to `1`, such as `0.97`.";
603
+ rdfs:domain :Person;
604
+ rdfs:range :Number .
605
+ [] a sh:PropertyShape; sh:path :oxygenSaturation; sh:targetSubjectsOf :oxygenSaturation; sh:maxCount 1 .
606
+ :sleepingWristTemperature a owl:DatatypeProperty;
607
+ :metric "gauge";
608
+ :unit "Cel";
609
+ rdfs:comment "The skin temperature at the wrist during sleep, in degrees Celsius.";
610
+ rdfs:domain :Person;
611
+ rdfs:range :Number .
612
+ [] a sh:PropertyShape; sh:path :sleepingWristTemperature; sh:targetSubjectsOf :sleepingWristTemperature; sh:maxCount 1 .
613
+ :weight a owl:DatatypeProperty;
614
+ :metric "gauge";
615
+ :unit "kg";
616
+ rdfs:comment "The person's body weight, as a mass in kilograms.";
617
+ rdfs:domain :Person;
618
+ rdfs:range :Number;
619
+ skos:closeMatch schemaorg:weight .
620
+ [] a sh:PropertyShape; sh:path :weight; sh:targetSubjectsOf :weight; sh:maxCount 1 .
621
+ :systolicBloodPressure a owl:DatatypeProperty;
622
+ :metric "gauge";
623
+ :unit "mm[Hg]";
624
+ rdfs:comment "The blood pressure while the heart beats, in millimeters of mercury.";
625
+ rdfs:domain :Person;
626
+ rdfs:range :Number .
627
+ [] a sh:PropertyShape; sh:path :systolicBloodPressure; sh:targetSubjectsOf :systolicBloodPressure; sh:maxCount 1 .
628
+ :diastolicBloodPressure a owl:DatatypeProperty;
629
+ :metric "gauge";
630
+ :unit "mm[Hg]";
631
+ rdfs:comment "The blood pressure between heartbeats, in millimeters of mercury.";
632
+ rdfs:domain :Person;
633
+ rdfs:range :Number .
634
+ [] a sh:PropertyShape; sh:path :diastolicBloodPressure; sh:targetSubjectsOf :diastolicBloodPressure; sh:maxCount 1 .
635
+ :stepCount a owl:DatatypeProperty;
636
+ :metric "sum";
637
+ :unit "{steps}";
638
+ rdfs:comment "The number of steps taken.";
639
+ rdfs:domain :Person;
640
+ rdfs:range :Number .
641
+ [] a sh:PropertyShape; sh:path :stepCount; sh:targetSubjectsOf :stepCount; sh:maxCount 1 .
642
+ :activeEnergyBurned a owl:DatatypeProperty;
643
+ :metric "sum";
644
+ :unit "kcal";
645
+ rdfs:comment "The energy burned by moving, beyond what the body burns at rest, in kilocalories.";
646
+ rdfs:domain :Person;
647
+ rdfs:range :Number .
648
+ [] a sh:PropertyShape; sh:path :activeEnergyBurned; sh:targetSubjectsOf :activeEnergyBurned; sh:maxCount 1 .
482
649
  :Post a owl:Class;
483
650
  rdfs:comment "A work published to a social or media platform, such as a feed post, a story, a reel, or a tweet. It can have a text :body and media files that it :contains. Its :sourceFormat is the platform's own format for it.";
484
651
  rdfs:subClassOf :CreativeWork;
485
652
  skos:broadMatch schemaorg:SocialMediaPosting .
486
653
  :PublishAction a owl:Class;
487
- rdfs:comment "The agent published or released the :object. The work's :datePublished is when this happened.";
654
+ rdfs:comment "The agent published or released a work, such as a post, a video, or a pull request. Its :result is the work, and the work's :datePublished is when this happened.";
488
655
  rdfs:subClassOf :CreateAction .
489
656
  :CreateAction a owl:Class;
490
657
  rdfs:comment "The agent brought a work into being. Its :result is the work. The subclasses name the kind of making.";
@@ -497,10 +664,26 @@
497
664
  rdfs:comment "The agent took a photograph. Its :result is the :ImageObject.";
498
665
  rdfs:subClassOf :CreateAction;
499
666
  skos:exactMatch schemaorg:PhotographAction .
667
+ :ScreenshotAction a owl:Class;
668
+ rdfs:comment "The agent captured what a screen showed, such as a web page or an app. Its :result is the :ImageObject. The image is a :snapshotOf the resource it shows, and the :object can name the page it was captured from.";
669
+ rdfs:subClassOf :CreateAction .
500
670
  :LikeAction a owl:Class;
501
671
  rdfs:comment "The agent liked the :object.";
502
672
  rdfs:subClassOf :ReactAction;
503
673
  skos:broadMatch schemaorg:LikeAction .
674
+ :UnlikeAction a owl:Class;
675
+ rdfs:comment "The agent withdrew a like of the :object, such as by removing a favorite.";
676
+ rdfs:subClassOf :ReactAction .
677
+ :likes a owl:ObjectProperty;
678
+ rdfs:comment "An entity the agent likes. A :LikeAction adds an entity to the agent's likes, and an :UnlikeAction removes it. A source can also give the agent's likes directly.";
679
+ rdfs:subPropertyOf :relation;
680
+ :assertedBy :LikeAction;
681
+ :retractedBy :UnlikeAction;
682
+ :runPredicate :liked;
683
+ rdfs:domain :Agent;
684
+ rdfs:range :Entity .
685
+ :liked a :DerivedProperty;
686
+ rdfs:comment "An agent's standing like for the object, opened by LikeAction and closed by UnlikeAction. The writable relationship is likes; this derived query name preserves the object-and-agent view of the action history." .
504
687
  :ReactAction a owl:Class;
505
688
  rdfs:comment "The agent took a stance on the :object with no content, such as a like. A reaction with content, such as an emoji or a comment, is a :RespondAction.";
506
689
  rdfs:subClassOf :AssessAction;
@@ -586,6 +769,10 @@
586
769
  rdfs:comment "One episode of a podcast.";
587
770
  rdfs:subClassOf :CreativeWork;
588
771
  skos:broadMatch schemaorg:PodcastEpisode .
772
+ :PodcastSeries a owl:Class;
773
+ rdfs:comment "A podcast, a series of episodes published through a :webFeed by a :publisher.";
774
+ rdfs:subClassOf :CreativeWork;
775
+ skos:broadMatch schemaorg:PodcastSeries .
589
776
  :attribution a owl:ObjectProperty;
590
777
  rdfs:comment "An agent responsible for bringing a work into being.";
591
778
  rdfs:subPropertyOf :relation;
@@ -629,6 +816,18 @@
629
816
  rdfs:range :MusicAlbum;
630
817
  skos:exactMatch schemaorg:inAlbum .
631
818
  [] a sh:PropertyShape; sh:path :inAlbum; sh:targetSubjectsOf :inAlbum; sh:maxCount 1 .
819
+ :series a owl:ObjectProperty;
820
+ :propagatesEncounter true;
821
+ rdfs:comment "The series that this work is one of, such as the podcast an episode belongs to or the series a book was published in.";
822
+ rdfs:subPropertyOf :partOf;
823
+ rdfs:domain :CreativeWork;
824
+ rdfs:range :CreativeWork;
825
+ skos:closeMatch schemaorg:partOfSeries .
826
+ :webFeed a owl:DatatypeProperty;
827
+ rdfs:comment "The URL of an RSS or Atom feed that publishes the work's items, such as a podcast's episodes or a blog's posts.";
828
+ rdfs:domain :CreativeWork;
829
+ rdfs:range :URL;
830
+ skos:exactMatch schemaorg:webFeed .
632
831
  :duration a owl:DatatypeProperty;
633
832
  rdfs:comment "How long the recording or media lasts.";
634
833
  rdfs:domain [ a owl:Class; owl:unionOf ( :AudioObject :VideoObject :MusicRecording :PodcastEpisode ) ];
@@ -717,10 +916,10 @@
717
916
  rdfs:comment "A period of using a device, such as a block of time with one app in focus. It is the :result of an :ExecuteAction, which gives its start and end. Its :subject is the resource in focus, and it :isPartOf a project. When no resource is in focus, its :name is the window's title.";
718
917
  rdfs:subClassOf :Session .
719
918
  :PhysicalObject a owl:Class;
720
- rdfs:comment "A physical object the subject owns or uses, such as a device, a vehicle, or a musical instrument. Its :category is its kind, such as `computer` or `car`, and its :model is its make and model. The subclasses name the roles an object plays in actions, such as :Device.";
919
+ rdfs:comment "A physical object the subject owns or uses, such as a device, a vehicle, or a musical instrument. Its :model is its make and model. The subclasses name the roles an object plays in actions, such as :Device.";
721
920
  rdfs:subClassOf :Entity .
722
921
  :Device a owl:Class;
723
- rdfs:comment "A physical computing device the subject runs software on, such as a computer, a phone, or a tablet. It is the :instrument of an :ExecuteAction. It names a role, not a kind, so its :category says what kind of device it is. It is :inRealm the logical machine, which can outlive the hardware.";
922
+ rdfs:comment "A physical computing device the subject runs software on, such as a computer, a phone, a tablet, or a watch. It is the :instrument of the actions done with it, such as an :ExecuteAction or a :MeasureAction. It names a role, not a kind, so its :model says what kind of device it is. It is :inRealm the logical machine, which can outlive the hardware.";
724
923
  rdfs:subClassOf :PhysicalObject .
725
924
  :ProductModel a owl:Class;
726
925
  rdfs:comment "A kind of product, such as a line of phones or one model of camera, rather than one particular product. One particular computing device is a :Device.";
@@ -740,7 +939,7 @@
740
939
  rdfs:domain :Session;
741
940
  rdfs:range :Entity .
742
941
  :model a owl:DatatypeProperty;
743
- rdfs:comment "The make and model of the object, such as `Mac17,9` or `iPhone15,2`. It is not the object's :name or its :category.";
942
+ rdfs:comment "The make and model of the object, such as `Mac17,9` or `iPhone15,2`. It is not the object's :name.";
744
943
  rdfs:domain :PhysicalObject;
745
944
  rdfs:range :Text;
746
945
  skos:exactMatch schemaorg:model .
@@ -803,6 +1002,10 @@
803
1002
  rdfs:comment "A written piece published on the web or in a periodical, such as a news story, a blog post, or a feed item.";
804
1003
  rdfs:subClassOf :CreativeWork;
805
1004
  skos:broadMatch schemaorg:Article .
1005
+ :Note a owl:Class;
1006
+ rdfs:comment "A text that its author keeps and edits, such as a note in a notes app or a page in a personal wiki. Its :body is its text. A document file, such as a PDF or an attachment, is a :DocumentObject.";
1007
+ rdfs:subClassOf :CreativeWork;
1008
+ skos:closeMatch schemaorg:NoteDigitalDocument .
806
1009
  :snapshotOf a owl:ObjectProperty;
807
1010
  rdfs:comment "The resource this media captured at a moment, such as the web page in a screenshot or an archive. The value is the resource itself, the entity with the URL. The media's type tells a screenshot from an archive.";
808
1011
  rdfs:subPropertyOf :relation;
@@ -840,11 +1043,22 @@
840
1043
  rdfs:range :Text;
841
1044
  skos:closeMatch schemaorg:keywords .
842
1045
  :caption a owl:DatatypeProperty;
843
- rdfs:comment "A caption or description of the image.";
844
- rdfs:domain :ImageObject;
1046
+ rdfs:comment "A caption or description of the picture or video, written by a person.";
1047
+ rdfs:domain [ a owl:Class; owl:unionOf ( :StillImage :MovingImage :ImageObject ) ];
845
1048
  rdfs:range :Text;
846
1049
  skos:exactMatch schemaorg:caption .
847
1050
  [] a sh:PropertyShape; sh:path :caption; sh:targetSubjectsOf :caption; sh:maxCount 1 .
1051
+ :exifData a owl:DatatypeProperty;
1052
+ rdfs:comment "What the image's file records about how it was taken, as EXIF tags. Each key is the tag's name in EXIF 3.0, such as `FNumber`, `ExposureTime`, or `LensModel`. Each value is the tag's value as EXIF defines it. A fraction is a decimal (`0.008`), a code is its number (`5`), and text is as written. Not allowed: another name for a tag (`ISO` for `PhotographicSensitivity`), a fraction as text (`1/125`), or a code's meaning (`Pattern`).";
1053
+ rdfs:domain :ImageObject;
1054
+ rdfs:range :JSONObject;
1055
+ skos:closeMatch schemaorg:exifData .
1056
+ [] a sh:PropertyShape; sh:path :exifData; sh:targetSubjectsOf :exifData; sh:maxCount 1 .
1057
+ :depicts a owl:ObjectProperty;
1058
+ rdfs:comment "Something that appears in the picture or video, such as a person, an animal, or a building.";
1059
+ rdfs:subPropertyOf :relation;
1060
+ rdfs:domain [ a owl:Class; owl:unionOf ( :StillImage :MovingImage ) ];
1061
+ rdfs:range :Entity .
848
1062
  :SoftwareSourceCode a owl:Class;
849
1063
  rdfs:comment "Source code as a work, such as a snippet, a script, or a program's code.";
850
1064
  rdfs:subClassOf :CreativeWork;
@@ -853,7 +1067,7 @@
853
1067
  rdfs:comment "A store of files and their history under version control, hosted on a forge or kept locally. It can hold source code, data, documents, or anything else. Work filed against it, such as tasks and changesets, :isPartOf it.";
854
1068
  rdfs:subClassOf :CreativeWork .
855
1069
  :Changeset a owl:Class;
856
- rdfs:comment "A set of changes to a work, proposed or applied as a unit, that can be revised until it is decided, such as a pull request or a suggested edit to a document. It :isPartOf the work it changes. A :PublishAction puts it forward. An :AcceptAction, :RejectAction, or :CancelAction then decides it.";
1070
+ rdfs:comment "A set of changes to a work, made as a unit, such as a pull request, a suggested edit to a document, or the text a writer added to a note in one sitting. Its :body is the text it adds. It :isPartOf the work it changes. One applied directly is the :result of the :UpdateAction that made it. One proposed is put forward by a :PublishAction and can be revised until an :AcceptAction, :RejectAction, or :CancelAction decides it. A version of a work, such as a commit, is a :Revision.";
857
1071
  rdfs:subClassOf :CreativeWork .
858
1072
  :AcceptAction a owl:Class;
859
1073
  rdfs:comment "The agent accepted what was put forward, such as merging a changeset into the work it changes. The :object is what was accepted.";
@@ -872,3 +1086,52 @@
872
1086
  skos:exactMatch schemaorg:isBasedOn;
873
1087
  rdfs:domain :CreativeWork;
874
1088
  rdfs:range :CreativeWork .
1089
+
1090
+ :TradeAction a owl:Class;
1091
+ rdfs:comment "The agent exchanged something of value with another agent, such as by buying, selling, or paying.";
1092
+ rdfs:subClassOf :Action;
1093
+ skos:broadMatch schemaorg:TradeAction .
1094
+ :PayAction a owl:Class;
1095
+ rdfs:comment "The agent paid money to another agent, such as for a purchase with a card. Its :result is the :FinancialTransaction, which gives how much was paid and to whom.";
1096
+ rdfs:subClassOf :TradeAction;
1097
+ skos:closeMatch schemaorg:PayAction .
1098
+ :FinancialTransaction a owl:Class;
1099
+ rdfs:comment "A movement of money, such as a card purchase, a transfer between accounts, or a trade. It is the :result of the action that moved the money, such as a :PayAction, which gives when it happened and who paid. Its :amount gives how much moved, and its :recipient is who received it. Its change to each account is a :FinancialPosting that is :isPartOf it.";
1100
+ rdfs:subClassOf :Intangible .
1101
+ :PaymentCard a owl:Class;
1102
+ rdfs:comment "A numbered card that payments draw on, such as a credit card or a debit card. It is the card as issued, so a card reissued with a new number is a new :PaymentCard, while the account behind it continues. The same card added to several devices is one :PaymentCard. It is the :instrument of a :PayAction, and the account it draws on is its :inAccount. Its :category is its kind, such as `credit` or `debit`.";
1103
+ rdfs:subClassOf :Intangible;
1104
+ skos:closeMatch schemaorg:PaymentCard .
1105
+ :MonetaryAmount a owl:Class;
1106
+ rdfs:comment "A sum of money: its :value in its :currency. It has no identity of its own.";
1107
+ rdfs:subClassOf :StructuredValue;
1108
+ skos:closeMatch schemaorg:MonetaryAmount .
1109
+ :value a owl:DatatypeProperty;
1110
+ rdfs:comment "The number of units of the :currency, such as `69.93`.";
1111
+ rdfs:domain :MonetaryAmount;
1112
+ rdfs:range :Number;
1113
+ skos:exactMatch schemaorg:value .
1114
+ [] a sh:PropertyShape; sh:path :value; sh:targetSubjectsOf :value; sh:maxCount 1 .
1115
+ :currency a owl:DatatypeProperty;
1116
+ rdfs:comment "The currency the :value is in, as its ISO 4217 code, such as `CAD` or `USD`. Not allowed: a symbol (`$`) or a name (`dollars`).";
1117
+ rdfs:domain :MonetaryAmount;
1118
+ rdfs:range :Text;
1119
+ skos:closeMatch schemaorg:currency .
1120
+ [] a sh:PropertyShape; sh:path :currency; sh:targetSubjectsOf :currency; sh:maxCount 1 .
1121
+ :amount a owl:ObjectProperty;
1122
+ rdfs:comment "How much money moved. On a :FinancialTransaction, it is the whole amount, and its :value is positive. The action that produced the transaction says who paid and who was paid. On a :FinancialPosting, it is the change to the posting's account, and its :value is signed. It is negative where the money came from and positive where it went. A positive value increases an asset or an expense account, and a negative one increases a liability, an income, or an equity account, so a purchase paid with a card is negative on the card's account.";
1123
+ rdfs:domain [ a owl:Class; owl:unionOf ( :FinancialTransaction :FinancialPosting ) ];
1124
+ rdfs:range :MonetaryAmount;
1125
+ skos:closeMatch schemaorg:amount .
1126
+ [] a sh:PropertyShape; sh:path :amount; sh:targetSubjectsOf :amount; sh:maxCount 1 .
1127
+ :FinancialAccount a owl:Class;
1128
+ rdfs:comment "An account that money is counted in, as one line of a chart of accounts. It is a real account held with an institution, such as a bank account or a credit card account, or a nominal one that classifies money, such as an expense or income category. Its :financialAccountType says which of the five kinds it is. The account above it in the chart is what it :isPartOf.";
1129
+ rdfs:subClassOf :Intangible .
1130
+ :FinancialPosting a owl:Class;
1131
+ rdfs:comment "One side of a :FinancialTransaction: the change it made to one :FinancialAccount. It is :isPartOf the transaction, its :inAccount is the account, and its :amount is the change. A negative amount is where the money came from, and a positive one is where it went. A transaction whose postings sum to zero is complete.";
1132
+ rdfs:subClassOf :Intangible .
1133
+ :financialAccountType a owl:DatatypeProperty;
1134
+ rdfs:comment "The kind of :FinancialAccount, one of `asset`, `liability`, `equity`, `income`, or `expense`. An asset is money held, a liability is money owed, income is where money comes from, expense is where it goes, and equity is what is left when liabilities are taken from assets. Not allowed: another kind (`credit-card`) or another case (`Asset`).";
1135
+ rdfs:domain :FinancialAccount;
1136
+ rdfs:range :Text .
1137
+ [] a sh:PropertyShape; sh:path :financialAccountType; sh:targetSubjectsOf :financialAccountType; sh:maxCount 1 .
@@ -0,0 +1,59 @@
1
+ import type { KeyField } from './schema.js';
2
+ /**
3
+ * A node's identity as one string, whatever its source or the shape of its
4
+ * `@key`: the hash of its keyset, the values of the fields its `@key` names.
5
+ * Extractors and stores derive it the same way, so one node can name another
6
+ * by it, such as from its text, without knowing how the other is keyed. The
7
+ * hash must never change: every stored identity is one.
8
+ */
9
+ /** A node, as far as its identity goes: its `@key` or `@id`, and the fields they name. */
10
+ export interface KeyedNode {
11
+ '@type'?: unknown;
12
+ '@key'?: KeyField[];
13
+ '@id'?: unknown;
14
+ }
15
+ /**
16
+ * The source a node identified by nothing but its URL belongs to. A URL is a
17
+ * portable identifier, like an email address or a phone number, so it belongs
18
+ * to no product, whichever source saw it.
19
+ */
20
+ export declare const URL_SOURCE = "url";
21
+ /**
22
+ * Deep, recursive, stable-key canonicalization: object keys are sorted at
23
+ * every level and undefined values dropped, so equal content always produces
24
+ * identical bytes. Array order is kept, since it means something. A `Date` is
25
+ * the ISO string a store gets for it, once it's serialized.
26
+ */
27
+ export declare function canonicalize(value: unknown): unknown;
28
+ /** Canonical JSON: the same string whatever order the keys were added in. */
29
+ export declare function canonicalJson(value: unknown): string;
30
+ /**
31
+ * Lowercase base32 (RFC 4648, no padding) of the sha256 of the bytes: 52
32
+ * characters, shorter than hex and safe in URLs and on case-insensitive
33
+ * filesystems.
34
+ */
35
+ export declare function base32Sha256(bytes: Uint8Array): string;
36
+ /**
37
+ * The hash of a keyset: the base32 sha256 of its canonical JSON, the same
38
+ * however its keys are ordered.
39
+ */
40
+ export declare function generateKeysetCID(keyset: Record<string, unknown>): string;
41
+ /**
42
+ * The keyset a node's `@key` names: each field's value by its path, with dots
43
+ * and `[*]` splats followed into nested values and a list joined with commas.
44
+ * `source` is the source given, and an `action.` field is read from the action
45
+ * the node is in. A computed entry `{ key, value }` is `key:value`. Fields
46
+ * with no value are left out, and a keyset with none is null, so it never
47
+ * names one node shared by unrelated records. A key of nothing but `url` is
48
+ * the `url` source's, so it names the same node whichever source saw it.
49
+ */
50
+ export declare function keysetOf(node: KeyedNode, source: string | undefined, actionContext?: Record<string, unknown>): Record<string, unknown> | null;
51
+ /**
52
+ * A node's identity: the hash of the keyset its `@key` names, or its `@id`,
53
+ * which is that hash already. With both, they must agree. With neither, it's
54
+ * its `url`, as the `url` source's, or else its `attachmentCid`, the stored
55
+ * file it is. `source` is the node's own unless given, as for a node in a
56
+ * record of that source that names none.
57
+ */
58
+ export declare function nodeKey(node: KeyedNode, source?: string | undefined, actionContext?: Record<string, unknown>): string;
59
+ //# sourceMappingURL=identity.d.ts.map