causalontology 2.0.0 → 4.0.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.
- checksums.yaml +4 -4
- data/README.md +56 -14
- data/conformance.rb +503 -11
- data/lib/causalontology/canonical.rb +14 -4
- data/lib/causalontology/schema.rb +14 -1
- data/lib/causalontology/semantics.rb +161 -16
- data/lib/causalontology/spec/schema/assertion.schema.json +75 -0
- data/lib/causalontology/spec/schema/attitude.schema.json +45 -0
- data/lib/causalontology/spec/schema/bridge.schema.json +46 -0
- data/lib/causalontology/spec/schema/causal_relation_object.schema.json +111 -0
- data/lib/causalontology/spec/schema/conduit.schema.json +56 -0
- data/lib/causalontology/spec/schema/continuant.schema.json +38 -0
- data/lib/causalontology/spec/schema/cross_stratal_seam.schema.json +50 -0
- data/lib/causalontology/spec/schema/enrichment.schema.json +80 -0
- data/lib/causalontology/spec/schema/individual.schema.json +36 -0
- data/lib/causalontology/spec/schema/occurrent.schema.json +42 -0
- data/lib/causalontology/spec/schema/port.schema.json +56 -0
- data/lib/causalontology/spec/schema/predicted_occurrence.schema.json +68 -0
- data/lib/causalontology/spec/schema/prediction_error.schema.json +37 -0
- data/lib/causalontology/spec/schema/quality.schema.json +44 -0
- data/lib/causalontology/spec/schema/realizable.schema.json +38 -0
- data/lib/causalontology/spec/schema/retraction.schema.json +43 -0
- data/lib/causalontology/spec/schema/state.schema.json +89 -0
- data/lib/causalontology/spec/schema/stratum.schema.json +52 -0
- data/lib/causalontology/spec/schema/succession.schema.json +39 -0
- data/lib/causalontology/spec/schema/token.schema.json +96 -0
- data/lib/causalontology/spec/schema/token_causal_claim.schema.json +76 -0
- data/lib/causalontology/store.rb +5 -2
- data/lib/causalontology.rb +17 -1
- metadata +23 -2
|
@@ -14,9 +14,13 @@ require_relative "jcs"
|
|
|
14
14
|
|
|
15
15
|
module Causalontology
|
|
16
16
|
module Canonical
|
|
17
|
-
# The identity-bearing fields of each of the
|
|
18
|
-
#
|
|
19
|
-
#
|
|
17
|
+
# The identity-bearing fields of each of the twenty-one kinds (3.0.0 adds the
|
|
18
|
+
# cross_stratal_seam; the conduit gains realized_by; 4.0.0 adds the attitude,
|
|
19
|
+
# the predicted_occurrence, and the prediction_error - all additive and
|
|
20
|
+
# identity-preserving - a record that omits a new field keeps its earlier
|
|
21
|
+
# identifier byte-for-byte, and the new kinds open new identity schemes that
|
|
22
|
+
# disturb no existing record). "type" is always injected, so it is not listed
|
|
23
|
+
# here. Order does not matter (JCS sorts keys).
|
|
20
24
|
IDENTITY_FIELDS = {
|
|
21
25
|
# ---- type tier ----
|
|
22
26
|
"occurrent" => ["label", "category", "stratum"],
|
|
@@ -26,8 +30,10 @@ module Causalontology
|
|
|
26
30
|
"realizable" => ["kind", "bearer", "label"],
|
|
27
31
|
"stratum" => ["label", "scheme", "ordinal", "unit", "governs"],
|
|
28
32
|
"bridge" => ["coarse", "fine", "relation"],
|
|
33
|
+
"cross_stratal_seam" => ["source", "target", "mechanism_status", "chain"],
|
|
29
34
|
"port" => ["bearer", "label", "direction", "accepts", "realizable"],
|
|
30
|
-
"conduit" => ["label", "from", "to", "carries", "transform"
|
|
35
|
+
"conduit" => ["label", "from", "to", "carries", "transform",
|
|
36
|
+
"realized_by"],
|
|
31
37
|
"quality" => ["label", "datatype", "unit", "stratum"],
|
|
32
38
|
# ---- token tier ----
|
|
33
39
|
"token_individual" => ["instantiates", "designator", "part_of"],
|
|
@@ -36,6 +42,10 @@ module Causalontology
|
|
|
36
42
|
"state_assertion" => ["subject", "quality", "value", "interval"],
|
|
37
43
|
"token_causal_claim" => ["causes", "effects", "covering_law",
|
|
38
44
|
"actual_delay", "counterfactual"],
|
|
45
|
+
"attitude" => ["holder", "attitude_type", "content"],
|
|
46
|
+
"predicted_occurrence" => ["instantiates", "interval", "predictor",
|
|
47
|
+
"strength"],
|
|
48
|
+
"prediction_error" => ["predicted", "observed", "discrepancy"],
|
|
39
49
|
# ---- provenance tier ----
|
|
40
50
|
"assertion" => ["about", "source", "evidence_type", "evidence", "strength",
|
|
41
51
|
"confidence", "timestamp", "evidenced_by"],
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# Schema validation against spec/schema/*.schema.json.
|
|
4
4
|
#
|
|
5
5
|
# A deliberately small interpreter for exactly the JSON Schema keywords the
|
|
6
|
-
#
|
|
6
|
+
# twenty-one Causalontology schemas use: type, const, enum, pattern, required,
|
|
7
7
|
# properties, additionalProperties, items, minItems, minLength, minimum,
|
|
8
8
|
# maximum, oneOf, local $ref (#/$defs/...), and cross-file $ref to a sibling
|
|
9
9
|
# schema (https://causalontology.org/schema/<file>.schema.json#/...). "format"
|
|
@@ -23,6 +23,7 @@ module Causalontology
|
|
|
23
23
|
"realizable" => "realizable.schema.json",
|
|
24
24
|
"stratum" => "stratum.schema.json",
|
|
25
25
|
"bridge" => "bridge.schema.json",
|
|
26
|
+
"cross_stratal_seam" => "cross_stratal_seam.schema.json",
|
|
26
27
|
"port" => "port.schema.json",
|
|
27
28
|
"conduit" => "conduit.schema.json",
|
|
28
29
|
"quality" => "quality.schema.json",
|
|
@@ -30,6 +31,9 @@ module Causalontology
|
|
|
30
31
|
"token_occurrence" => "token.schema.json",
|
|
31
32
|
"state_assertion" => "state.schema.json",
|
|
32
33
|
"token_causal_claim" => "token_causal_claim.schema.json",
|
|
34
|
+
"attitude" => "attitude.schema.json",
|
|
35
|
+
"predicted_occurrence" => "predicted_occurrence.schema.json",
|
|
36
|
+
"prediction_error" => "prediction_error.schema.json",
|
|
33
37
|
"assertion" => "assertion.schema.json",
|
|
34
38
|
"enrichment" => "enrichment.schema.json",
|
|
35
39
|
"retraction" => "retraction.schema.json",
|
|
@@ -41,9 +45,18 @@ module Causalontology
|
|
|
41
45
|
@cache = {}
|
|
42
46
|
|
|
43
47
|
class << self
|
|
48
|
+
# Where the twenty-one *.schema.json files live, in strict precedence:
|
|
49
|
+
#
|
|
50
|
+
# (a) $CAUSALONTOLOGY_SPEC/schema - explicit override, always wins;
|
|
51
|
+
# (b) the copy vendored inside the gem - what an installed consumer
|
|
52
|
+
# uses, so validation works standalone with no repository present;
|
|
53
|
+
# (c) the repository-relative path - last resort, for working directly
|
|
54
|
+
# in a checkout where (b) has not been vendored yet.
|
|
44
55
|
def schema_dir
|
|
45
56
|
env = ENV["CAUSALONTOLOGY_SPEC"]
|
|
46
57
|
return File.join(env, "schema") if env && !env.empty?
|
|
58
|
+
bundled = File.expand_path("spec/schema", __dir__)
|
|
59
|
+
return bundled if File.directory?(bundled)
|
|
47
60
|
# lib/causalontology -> lib -> ruby -> bindings -> repository root
|
|
48
61
|
File.expand_path("../../../../spec/schema", __dir__)
|
|
49
62
|
end
|
|
@@ -22,6 +22,13 @@ module Causalontology
|
|
|
22
22
|
"years" => 31556952,
|
|
23
23
|
}.freeze
|
|
24
24
|
|
|
25
|
+
# 3.0.0: the ordinal (dimensionless) temporal units. A tick is a discrete
|
|
26
|
+
# step with NO wall-clock mapping; a tick window is ordered by integer
|
|
27
|
+
# comparison, and an ordinal window and a wall-clock window are DIFFERENT
|
|
28
|
+
# DIMENSIONS that do not compare (mixing them is never within-window and
|
|
29
|
+
# never overlapping).
|
|
30
|
+
ORDINAL_UNITS = Set.new(["ticks"]).freeze
|
|
31
|
+
|
|
25
32
|
# Rule 12: enrichment field-to-kind validity and entry shapes. Two
|
|
26
33
|
# occurrent forms added in 2.0.0.
|
|
27
34
|
ENRICHMENT_FIELDS = {
|
|
@@ -47,6 +54,19 @@ module Causalontology
|
|
|
47
54
|
Canonical::KIND_OF_PREFIX[identifier.split(":", 2)[0]]
|
|
48
55
|
end
|
|
49
56
|
|
|
57
|
+
# 3.0.0: "ordinal" for a tick-like unit, else "wallclock".
|
|
58
|
+
def dimension(unit)
|
|
59
|
+
ORDINAL_UNITS.include?(unit) ? "ordinal" : "wallclock"
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# 3.0.0: a comparable magnitude within ONE dimension: raw tick count for an
|
|
63
|
+
# ordinal unit, seconds for a wall-clock unit. Never mix dimensions.
|
|
64
|
+
def magnitude(value, unit)
|
|
65
|
+
return value if ORDINAL_UNITS.include?(unit) # a dimensionless tick count
|
|
66
|
+
return 0 if unit == "instant"
|
|
67
|
+
value * UNIT_SECONDS.fetch(unit)
|
|
68
|
+
end
|
|
69
|
+
|
|
50
70
|
# [ok, reasons] - the locally checkable semantic rules.
|
|
51
71
|
def validate_semantics(obj, kind = nil)
|
|
52
72
|
kind ||= Canonical.infer_kind(obj)
|
|
@@ -96,6 +116,41 @@ module Causalontology
|
|
|
96
116
|
end
|
|
97
117
|
end
|
|
98
118
|
|
|
119
|
+
# 3.0.0 Rule 22, local clause: a Cross Stratal Seam that DRAWS a chain has,
|
|
120
|
+
# by drawing it, a modelled intervening mechanism - so mechanism_status
|
|
121
|
+
# 'absent' contradicts a present chain (the honest-ignorance distinction
|
|
122
|
+
# must stay honest). The stratal well-formedness (non-adjacency, adjacency
|
|
123
|
+
# of chain steps, scheme, the home rule) needs the strata map and lives in
|
|
124
|
+
# seam_wellformed, exactly as bridge well-formedness does.
|
|
125
|
+
if kind == "cross_stratal_seam"
|
|
126
|
+
if !obj["chain"].nil? && obj["mechanism_status"] == "absent"
|
|
127
|
+
errors << "contradictory_seam: a drawn chain cannot carry " \
|
|
128
|
+
"mechanism_status 'absent' (a drawn mechanism is not absent)"
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# 4.0.0 Rule 24, local clause: a predicted_occurrence's interval carries
|
|
133
|
+
# exactly ONE temporal dimension - a wall-clock start (optional end) or an
|
|
134
|
+
# ordinal start_tick (optional end_tick), never both and never neither.
|
|
135
|
+
# Per Rule 23 the two dimensions never compare. The pairing check of a
|
|
136
|
+
# prediction_error against its predicted_occurrence and its observed
|
|
137
|
+
# token_occurrence needs those objects and lives in
|
|
138
|
+
# prediction_pairing_mismatch, exactly as covering_law_mismatch does.
|
|
139
|
+
if kind == "predicted_occurrence"
|
|
140
|
+
iv = obj["interval"] || {}
|
|
141
|
+
wall = iv.key?("start")
|
|
142
|
+
tick = iv.key?("start_tick")
|
|
143
|
+
if wall && tick
|
|
144
|
+
errors << "dimension_conflict: a predicted interval must " \
|
|
145
|
+
"carry exactly one temporal dimension, not a " \
|
|
146
|
+
"wall-clock start AND an ordinal start_tick"
|
|
147
|
+
end
|
|
148
|
+
if !wall && !tick
|
|
149
|
+
errors << "missing_dimension: a predicted interval must " \
|
|
150
|
+
"carry a wall-clock start or an ordinal start_tick"
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
99
154
|
[errors.empty?, errors]
|
|
100
155
|
end
|
|
101
156
|
|
|
@@ -105,26 +160,27 @@ module Causalontology
|
|
|
105
160
|
[!missing.empty?, missing]
|
|
106
161
|
end
|
|
107
162
|
|
|
108
|
-
# Rule 4: temporal admissibility
|
|
109
|
-
|
|
163
|
+
# Rule 4: temporal admissibility. For a wall-clock window `elapsed` is in
|
|
164
|
+
# seconds; for an ordinal ('ticks') window `elapsed` is a tick count.
|
|
165
|
+
# Ordering is by magnitude WITHIN the window's own dimension (3.0.0).
|
|
166
|
+
def admissible(cro, elapsed)
|
|
110
167
|
t = cro["temporal"]
|
|
111
168
|
return true if t.nil? # no window imposes no constraint
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
lo <= elapsed_seconds && elapsed_seconds <= hi
|
|
169
|
+
lo = magnitude(t["minimum_delay"], t["unit"])
|
|
170
|
+
hi = magnitude(t["maximum_delay"], t["unit"])
|
|
171
|
+
lo <= elapsed && elapsed <= hi
|
|
116
172
|
end
|
|
117
173
|
|
|
118
174
|
def window_overlap(a, b)
|
|
119
175
|
ta = a["temporal"]
|
|
120
176
|
tb = b["temporal"]
|
|
121
177
|
return true if ta.nil? || tb.nil? # either absent counts as overlapping
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
lo_a = ta["minimum_delay"]
|
|
125
|
-
hi_a = ta["maximum_delay"]
|
|
126
|
-
lo_b = tb["minimum_delay"]
|
|
127
|
-
hi_b = tb["maximum_delay"]
|
|
178
|
+
# 3.0.0: an ordinal window and a wall-clock window never overlap
|
|
179
|
+
return false if dimension(ta["unit"]) != dimension(tb["unit"])
|
|
180
|
+
lo_a = magnitude(ta["minimum_delay"], ta["unit"])
|
|
181
|
+
hi_a = magnitude(ta["maximum_delay"], ta["unit"])
|
|
182
|
+
lo_b = magnitude(tb["minimum_delay"], tb["unit"])
|
|
183
|
+
hi_b = magnitude(tb["maximum_delay"], tb["unit"])
|
|
128
184
|
lo_a <= hi_b && lo_b <= hi_a
|
|
129
185
|
end
|
|
130
186
|
|
|
@@ -309,19 +365,31 @@ module Causalontology
|
|
|
309
365
|
end
|
|
310
366
|
|
|
311
367
|
# ALGORITHM E helper: normalize a delay to seconds by the fixed table.
|
|
368
|
+
# 3.0.0: an ordinal ('ticks') unit is dimensionless and has NO wall-clock
|
|
369
|
+
# mapping - converting one to seconds is a category error and is refused.
|
|
312
370
|
def to_seconds(duration, unit)
|
|
371
|
+
if ORDINAL_UNITS.include?(unit)
|
|
372
|
+
raise ArgumentError,
|
|
373
|
+
"'#{unit}' is an ordinal (dimensionless) unit and has no " \
|
|
374
|
+
"wall-clock seconds mapping"
|
|
375
|
+
end
|
|
313
376
|
return 0 if unit == "instant"
|
|
314
377
|
duration * UNIT_SECONDS.fetch(unit)
|
|
315
378
|
end
|
|
316
379
|
|
|
317
380
|
# ALGORITHM E (Rule 20): does an observed delay fall within a covering
|
|
318
|
-
# law's temporal window? Inclusive at both ends (N12.5.2).
|
|
381
|
+
# law's temporal window? Inclusive at both ends (N12.5.2). 3.0.0: an ordinal
|
|
382
|
+
# delay compares to an ordinal window by integer tick count; an ordinal
|
|
383
|
+
# delay and a wall-clock window (or vice versa) are different dimensions and
|
|
384
|
+
# never fall within one another.
|
|
319
385
|
def delay_within_window(actual_delay, temporal)
|
|
320
386
|
return true if actual_delay.nil? || actual_delay.empty? ||
|
|
321
387
|
temporal.nil? || temporal.empty?
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
388
|
+
# dimension mismatch: a tick delay is not within a wall-clock window
|
|
389
|
+
return false if dimension(actual_delay["unit"]) != dimension(temporal["unit"])
|
|
390
|
+
observed = magnitude(actual_delay["duration"], actual_delay["unit"])
|
|
391
|
+
lo = magnitude(temporal["minimum_delay"], temporal["unit"])
|
|
392
|
+
hi = magnitude(temporal["maximum_delay"], temporal["unit"])
|
|
325
393
|
lo <= observed && observed <= hi
|
|
326
394
|
end
|
|
327
395
|
|
|
@@ -348,6 +416,73 @@ module Causalontology
|
|
|
348
416
|
[true, "well-formed bridge"]
|
|
349
417
|
end
|
|
350
418
|
|
|
419
|
+
# 3.0.0 Rule 22 / Algorithm F: Cross Stratal Seam well-formedness.
|
|
420
|
+
# [ok, reason]. All of (a)-(g) must hold, else malformed_seam. A seam is a
|
|
421
|
+
# MANAGED jump across NON-ADJACENT strata; when it DRAWS a chain, the chain
|
|
422
|
+
# must be an adjacent-stratum path spanning the two endpoints' strata.
|
|
423
|
+
def seam_wellformed(seam, occ_map, stratum_map)
|
|
424
|
+
src_s = (occ_map[seam["source"]] || {})["stratum"]
|
|
425
|
+
tgt_s = (occ_map[seam["target"]] || {})["stratum"]
|
|
426
|
+
if src_s.nil? || tgt_s.nil?
|
|
427
|
+
return [false, "malformed_seam: an endpoint has no stratum (a)"]
|
|
428
|
+
end
|
|
429
|
+
if stratum_map[src_s]["scheme"] != stratum_map[tgt_s]["scheme"]
|
|
430
|
+
return [false, "malformed_seam: endpoints differ in scheme (b)"]
|
|
431
|
+
end
|
|
432
|
+
so = stratum_map[src_s]["ordinal"]
|
|
433
|
+
to_ = stratum_map[tgt_s]["ordinal"]
|
|
434
|
+
if (so - to_).abs <= 1
|
|
435
|
+
return [false, "malformed_seam: endpoints are adjacent or co-stratal; " \
|
|
436
|
+
"a seam is for NON-adjacent strata (c)"]
|
|
437
|
+
end
|
|
438
|
+
chain = seam["chain"]
|
|
439
|
+
unless chain.nil?
|
|
440
|
+
if seam["mechanism_status"] == "absent"
|
|
441
|
+
return [false, "malformed_seam: a drawn chain contradicts " \
|
|
442
|
+
"mechanism_status 'absent' (d)"]
|
|
443
|
+
end
|
|
444
|
+
lo = [so, to_].min
|
|
445
|
+
hi = [so, to_].max
|
|
446
|
+
ords = []
|
|
447
|
+
chain.each do |oid|
|
|
448
|
+
st = (occ_map[oid] || {})["stratum"]
|
|
449
|
+
if st.nil?
|
|
450
|
+
return [false, "malformed_seam: a chain member has no stratum (e)"]
|
|
451
|
+
end
|
|
452
|
+
if stratum_map[st]["scheme"] != stratum_map[src_s]["scheme"]
|
|
453
|
+
return [false, "malformed_seam: a chain member differs in scheme (e)"]
|
|
454
|
+
end
|
|
455
|
+
ords << stratum_map[st]["ordinal"]
|
|
456
|
+
end
|
|
457
|
+
unless ords.all? { |o| lo < o && o < hi }
|
|
458
|
+
return [false, "malformed_seam: a chain member is not at an " \
|
|
459
|
+
"INTERVENING stratum, strictly between the endpoints (f)"]
|
|
460
|
+
end
|
|
461
|
+
diffs = (0...(ords.length - 1)).map { |i| ords[i + 1] - ords[i] }
|
|
462
|
+
if !diffs.empty? &&
|
|
463
|
+
!(diffs.all? { |d| d > 0 } || diffs.all? { |d| d < 0 })
|
|
464
|
+
return [false, "malformed_seam: chain is not strictly monotone from " \
|
|
465
|
+
"one endpoint toward the other (g)"]
|
|
466
|
+
end
|
|
467
|
+
end
|
|
468
|
+
[true, "well-formed cross_stratal_seam"]
|
|
469
|
+
end
|
|
470
|
+
|
|
471
|
+
# THE HOME RULE (3.0.0): a Cross Stratal Seam belongs to the COARSEST stratum
|
|
472
|
+
# it touches - the endpoint of the greater ordinal. Returns that stratum's
|
|
473
|
+
# identifier (nil if an endpoint is unstratified). A layer-to-stratum binding
|
|
474
|
+
# places and checks the seam by this rule.
|
|
475
|
+
def seam_home(seam, occ_map, stratum_map)
|
|
476
|
+
src_s = (occ_map[seam["source"]] || {})["stratum"]
|
|
477
|
+
tgt_s = (occ_map[seam["target"]] || {})["stratum"]
|
|
478
|
+
return nil if src_s.nil? || tgt_s.nil?
|
|
479
|
+
if stratum_map[src_s]["ordinal"] >= stratum_map[tgt_s]["ordinal"]
|
|
480
|
+
src_s
|
|
481
|
+
else
|
|
482
|
+
tgt_s
|
|
483
|
+
end
|
|
484
|
+
end
|
|
485
|
+
|
|
351
486
|
# Rule 17 / N4.2.1-2: Conduit well-formedness. [ok, reason]. N4.2.1 with
|
|
352
487
|
# the transform exception of N4.2.2.
|
|
353
488
|
def conduit_wellformed(conduit, port_map, cro_map = nil)
|
|
@@ -417,6 +552,16 @@ module Causalontology
|
|
|
417
552
|
false
|
|
418
553
|
end
|
|
419
554
|
|
|
555
|
+
# 4.0.0 Rule 24: prediction-to-observation pairing. True iff the prediction
|
|
556
|
+
# error's observed token does not instantiate the occurrent its
|
|
557
|
+
# predicted_occurrence instantiates (surfaces pairing_mismatch). An ABSENT
|
|
558
|
+
# observed is never a mismatch - it means the predicted occurrence was not
|
|
559
|
+
# fulfilled by any recorded occurrence.
|
|
560
|
+
def prediction_pairing_mismatch(error, predicted, observed)
|
|
561
|
+
return false if error["observed"].nil? || observed.nil?
|
|
562
|
+
observed["instantiates"] != predicted["instantiates"]
|
|
563
|
+
end
|
|
564
|
+
|
|
420
565
|
# Rule 21: true iff any cause token starts after any effect token (HARD;
|
|
421
566
|
# retrocausal_claim). RFC 3339 UTC "Z" strings compare lexicographically.
|
|
422
567
|
def retrocausal(tcc, token_map)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://causalontology.org/schema/assertion.schema.json",
|
|
4
|
+
"title": "Assertion",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": [
|
|
7
|
+
"id",
|
|
8
|
+
"about",
|
|
9
|
+
"source",
|
|
10
|
+
"evidence_type",
|
|
11
|
+
"confidence",
|
|
12
|
+
"timestamp"
|
|
13
|
+
],
|
|
14
|
+
"additionalProperties": false,
|
|
15
|
+
"properties": {
|
|
16
|
+
"id": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"pattern": "^assertion:[0-9a-f]{64}$"
|
|
19
|
+
},
|
|
20
|
+
"type": {
|
|
21
|
+
"const": "assertion"
|
|
22
|
+
},
|
|
23
|
+
"about": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"pattern": "^(causal_relation_object|occurrent|continuant|realizable|stratum|bridge|cross_stratal_seam|port|conduit|quality|token_individual|token_occurrence|state_assertion|token_causal_claim|attitude|predicted_occurrence|prediction_error):[0-9a-f]{64}$",
|
|
26
|
+
"description": "the content object this assertion is about (widened in 2.0.0 to the nine new content kinds; widened in 4.0.0 to attitude, predicted_occurrence, and prediction_error, and to the cross_stratal_seam, whose absence here was a 3.0.0 drift repaired in this major version); about a non-causal object it means the source vouches for the vocabulary item"
|
|
27
|
+
},
|
|
28
|
+
"source": {
|
|
29
|
+
"type": "string",
|
|
30
|
+
"pattern": "^ed25519:[0-9a-f]{64}$"
|
|
31
|
+
},
|
|
32
|
+
"evidence_type": {
|
|
33
|
+
"enum": [
|
|
34
|
+
"intervention",
|
|
35
|
+
"observation",
|
|
36
|
+
"simulation",
|
|
37
|
+
"derivation",
|
|
38
|
+
"human_hint",
|
|
39
|
+
"imported"
|
|
40
|
+
],
|
|
41
|
+
"description": "how the source came to the claim; ordering from strongest to weakest is intervention, observation, simulation, derivation, human_hint, imported (2.0.0 6.2)"
|
|
42
|
+
},
|
|
43
|
+
"evidence": {
|
|
44
|
+
"type": "string"
|
|
45
|
+
},
|
|
46
|
+
"strength": {
|
|
47
|
+
"type": "number",
|
|
48
|
+
"minimum": 0,
|
|
49
|
+
"maximum": 1,
|
|
50
|
+
"description": "the source's estimate of causal strength (semantics.md rule 5); meaningful only when about references a Causal Relation Object"
|
|
51
|
+
},
|
|
52
|
+
"confidence": {
|
|
53
|
+
"type": "number",
|
|
54
|
+
"minimum": 0,
|
|
55
|
+
"maximum": 1
|
|
56
|
+
},
|
|
57
|
+
"timestamp": {
|
|
58
|
+
"type": "string",
|
|
59
|
+
"format": "date-time"
|
|
60
|
+
},
|
|
61
|
+
"evidenced_by": {
|
|
62
|
+
"type": "array",
|
|
63
|
+
"items": {
|
|
64
|
+
"type": "string",
|
|
65
|
+
"pattern": "^(token_occurrence|token_causal_claim|state_assertion):[0-9a-f]{64}$"
|
|
66
|
+
},
|
|
67
|
+
"description": "the PARTICULAR token records that are the evidence for this claim (2.0.0 6.2). IDENTITY-BEARING."
|
|
68
|
+
},
|
|
69
|
+
"signature": {
|
|
70
|
+
"type": "string",
|
|
71
|
+
"pattern": "^[0-9a-f]{128}$",
|
|
72
|
+
"description": "Ed25519 signature over the record's canonical identity-bearing bytes; excluded from the identity hash"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://causalontology.org/schema/attitude.schema.json",
|
|
4
|
+
"title": "Attitude",
|
|
5
|
+
"description": "4.0.0. A first-class record of a PROPOSITIONAL ATTITUDE: what a holder's mind CONTAINS, never what is true. The holder is a MODELED agent inside the ontology (a continuant type or a particular token individual), never a cryptographic key; the content is a reference by identity to ANY content object - which may be FALSE, and may itself be another attitude (nesting). An attitude is NOT an assertion and carries no strength (Principle P4): it is asserted, graded, and retracted through the ordinary provenance layer, and the SOURCE that signs an assertion ABOUT an attitude is a different thing from the HOLDER of the attitude (Rule 25).",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"id",
|
|
9
|
+
"type",
|
|
10
|
+
"holder",
|
|
11
|
+
"attitude_type",
|
|
12
|
+
"content"
|
|
13
|
+
],
|
|
14
|
+
"additionalProperties": false,
|
|
15
|
+
"properties": {
|
|
16
|
+
"id": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"pattern": "^attitude:[0-9a-f]{64}$"
|
|
19
|
+
},
|
|
20
|
+
"type": {
|
|
21
|
+
"const": "attitude"
|
|
22
|
+
},
|
|
23
|
+
"holder": {
|
|
24
|
+
"type": "string",
|
|
25
|
+
"pattern": "^(continuant|token_individual):[0-9a-f]{64}$",
|
|
26
|
+
"description": "the agent whose mind contains the content: a MODELED agent inside the ontology (a continuant type or a particular token individual), never a cryptographic key - the signer of an assertion about this attitude is a SOURCE, and the two are different things (Rule 25)"
|
|
27
|
+
},
|
|
28
|
+
"attitude_type": {
|
|
29
|
+
"enum": [
|
|
30
|
+
"believes",
|
|
31
|
+
"desires",
|
|
32
|
+
"intends",
|
|
33
|
+
"knows",
|
|
34
|
+
"expects",
|
|
35
|
+
"fears"
|
|
36
|
+
],
|
|
37
|
+
"description": "CLOSED enumeration; extending it is a MAJOR change (Locked Decision 24)"
|
|
38
|
+
},
|
|
39
|
+
"content": {
|
|
40
|
+
"type": "string",
|
|
41
|
+
"pattern": "^(occurrent|causal_relation_object|continuant|realizable|stratum|bridge|cross_stratal_seam|port|conduit|quality|token_individual|token_occurrence|state_assertion|token_causal_claim|attitude|predicted_occurrence|prediction_error):[0-9a-f]{64}$",
|
|
42
|
+
"description": "a reference by identity to ANY content object, INCLUDING another attitude (nesting: A believes that B believes X). The content records what the holder's mind contains, not what is true - it may be FALSE, and a content that contradicts the actual record raises NO conflict (Rule 25: that mismatch IS a false belief, first-class and shareable)"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://causalontology.org/schema/bridge.schema.json",
|
|
4
|
+
"title": "Bridge",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": [
|
|
7
|
+
"id",
|
|
8
|
+
"type",
|
|
9
|
+
"coarse",
|
|
10
|
+
"fine",
|
|
11
|
+
"relation"
|
|
12
|
+
],
|
|
13
|
+
"additionalProperties": false,
|
|
14
|
+
"properties": {
|
|
15
|
+
"id": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"pattern": "^bridge:[0-9a-f]{64}$"
|
|
18
|
+
},
|
|
19
|
+
"type": {
|
|
20
|
+
"const": "bridge"
|
|
21
|
+
},
|
|
22
|
+
"coarse": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"pattern": "^occurrent:[0-9a-f]{64}$",
|
|
25
|
+
"description": "the occurrent at the coarser stratum"
|
|
26
|
+
},
|
|
27
|
+
"fine": {
|
|
28
|
+
"type": "array",
|
|
29
|
+
"minItems": 1,
|
|
30
|
+
"items": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"pattern": "^occurrent:[0-9a-f]{64}$"
|
|
33
|
+
},
|
|
34
|
+
"description": "the occurrents at the finer stratum that jointly constitute, aggregate to, realize, or subvene the coarse one"
|
|
35
|
+
},
|
|
36
|
+
"relation": {
|
|
37
|
+
"enum": [
|
|
38
|
+
"constitutes",
|
|
39
|
+
"aggregates",
|
|
40
|
+
"realizes",
|
|
41
|
+
"supervenes_on"
|
|
42
|
+
],
|
|
43
|
+
"description": "the cross-stratal relation asserted; CLOSED enumeration"
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://causalontology.org/schema/causal_relation_object.schema.json",
|
|
4
|
+
"title": "Causal Relation Object",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": [
|
|
7
|
+
"id",
|
|
8
|
+
"causes",
|
|
9
|
+
"effects"
|
|
10
|
+
],
|
|
11
|
+
"additionalProperties": false,
|
|
12
|
+
"properties": {
|
|
13
|
+
"id": {
|
|
14
|
+
"$ref": "#/$defs/croId"
|
|
15
|
+
},
|
|
16
|
+
"type": {
|
|
17
|
+
"const": "causal_relation_object"
|
|
18
|
+
},
|
|
19
|
+
"causes": {
|
|
20
|
+
"type": "array",
|
|
21
|
+
"minItems": 1,
|
|
22
|
+
"items": {
|
|
23
|
+
"$ref": "#/$defs/occId"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"effects": {
|
|
27
|
+
"type": "array",
|
|
28
|
+
"minItems": 1,
|
|
29
|
+
"items": {
|
|
30
|
+
"$ref": "#/$defs/occId"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"mechanism": {
|
|
34
|
+
"type": "array",
|
|
35
|
+
"items": {
|
|
36
|
+
"$ref": "#/$defs/croId"
|
|
37
|
+
},
|
|
38
|
+
"description": "identifiers of finer Causal Relation Objects whose composition realizes this one (hierarchical decomposition; must be acyclic; consistency per semantics.md rule 7, amended to BRIDGED reachability in 2.0.0)"
|
|
39
|
+
},
|
|
40
|
+
"temporal": {
|
|
41
|
+
"$ref": "#/$defs/temporalWindow"
|
|
42
|
+
},
|
|
43
|
+
"modality": {
|
|
44
|
+
"enum": [
|
|
45
|
+
"necessary",
|
|
46
|
+
"sufficient",
|
|
47
|
+
"contributory",
|
|
48
|
+
"preventive",
|
|
49
|
+
"enabling"
|
|
50
|
+
]
|
|
51
|
+
},
|
|
52
|
+
"context": {
|
|
53
|
+
"type": "array",
|
|
54
|
+
"items": {
|
|
55
|
+
"$ref": "#/$defs/occId"
|
|
56
|
+
},
|
|
57
|
+
"description": "enabling conditions under which the relation holds"
|
|
58
|
+
},
|
|
59
|
+
"refines": {
|
|
60
|
+
"$ref": "#/$defs/croId",
|
|
61
|
+
"description": "the more partial Causal Relation Object this one enriches (lineage; acyclic; must preserve the parent's specified fields)"
|
|
62
|
+
},
|
|
63
|
+
"skips": {
|
|
64
|
+
"type": "boolean",
|
|
65
|
+
"description": "TRUE asserts that this relation crosses non-adjacent strata WITHOUT being re-encoded at the intervening strata: the absence of a mechanism is a POSITIVE FINDING, not a gap (2.0.0 4.4)"
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
"$defs": {
|
|
69
|
+
"croId": {
|
|
70
|
+
"type": "string",
|
|
71
|
+
"pattern": "^causal_relation_object:[0-9a-f]{64}$"
|
|
72
|
+
},
|
|
73
|
+
"occId": {
|
|
74
|
+
"type": "string",
|
|
75
|
+
"pattern": "^occurrent:[0-9a-f]{64}$"
|
|
76
|
+
},
|
|
77
|
+
"temporalWindow": {
|
|
78
|
+
"type": "object",
|
|
79
|
+
"required": [
|
|
80
|
+
"minimum_delay",
|
|
81
|
+
"maximum_delay",
|
|
82
|
+
"unit"
|
|
83
|
+
],
|
|
84
|
+
"additionalProperties": false,
|
|
85
|
+
"properties": {
|
|
86
|
+
"minimum_delay": {
|
|
87
|
+
"type": "number",
|
|
88
|
+
"minimum": 0
|
|
89
|
+
},
|
|
90
|
+
"maximum_delay": {
|
|
91
|
+
"type": "number",
|
|
92
|
+
"minimum": 0
|
|
93
|
+
},
|
|
94
|
+
"unit": {
|
|
95
|
+
"enum": [
|
|
96
|
+
"instant",
|
|
97
|
+
"seconds",
|
|
98
|
+
"minutes",
|
|
99
|
+
"hours",
|
|
100
|
+
"days",
|
|
101
|
+
"weeks",
|
|
102
|
+
"months",
|
|
103
|
+
"years",
|
|
104
|
+
"ticks"
|
|
105
|
+
],
|
|
106
|
+
"description": "3.0.0: the wall-clock units carry a fixed seconds mapping; 'ticks' is a discrete, dimensionless ORDINAL unit (a step counter) with NO wall-clock mapping - a tick window is ordered by integer comparison, and a tick window and a wall-clock window are different dimensions that do not compare."
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://causalontology.org/schema/conduit.schema.json",
|
|
4
|
+
"title": "Conduit",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"required": [
|
|
7
|
+
"id",
|
|
8
|
+
"type",
|
|
9
|
+
"from",
|
|
10
|
+
"to",
|
|
11
|
+
"carries"
|
|
12
|
+
],
|
|
13
|
+
"additionalProperties": false,
|
|
14
|
+
"properties": {
|
|
15
|
+
"id": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"pattern": "^conduit:[0-9a-f]{64}$"
|
|
18
|
+
},
|
|
19
|
+
"type": {
|
|
20
|
+
"const": "conduit"
|
|
21
|
+
},
|
|
22
|
+
"label": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"pattern": "^[a-z][a-z0-9_]*$",
|
|
25
|
+
"description": "the name of the connection (for example: corticospinal_tract)"
|
|
26
|
+
},
|
|
27
|
+
"from": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"pattern": "^port:[0-9a-f]{64}$"
|
|
30
|
+
},
|
|
31
|
+
"to": {
|
|
32
|
+
"type": "string",
|
|
33
|
+
"pattern": "^port:[0-9a-f]{64}$"
|
|
34
|
+
},
|
|
35
|
+
"carries": {
|
|
36
|
+
"type": "array",
|
|
37
|
+
"minItems": 1,
|
|
38
|
+
"items": {
|
|
39
|
+
"type": "string",
|
|
40
|
+
"pattern": "^occurrent:[0-9a-f]{64}$"
|
|
41
|
+
},
|
|
42
|
+
"description": "the kinds of occurrent this conduit conducts"
|
|
43
|
+
},
|
|
44
|
+
"transform": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"pattern": "^causal_relation_object:[0-9a-f]{64}$",
|
|
47
|
+
"description": "OPTIONAL. ABSENT asserts the conduit is TRANSMISSIVE. PRESENT names the Causal Relation Object the conduit performs upon what it carries, asserting the conduit is COMPUTATIONAL."
|
|
48
|
+
},
|
|
49
|
+
"realized_by": {
|
|
50
|
+
"type": "string",
|
|
51
|
+
"pattern": "^[a-z][a-z0-9_]*:.+$",
|
|
52
|
+
"minLength": 3,
|
|
53
|
+
"description": "3.0.0 OPTIONAL. A scheme-qualified REFERENCE, by identity, to the native law or signal that REALIZES this conduit's transform (for example a native rate law a computational conduit stands for, or a runtime signal a transmissive conduit stands for). It is a reference, not an embedded law - the native dynamics stay native; the standard only records the binding. ABSENT (unbound) is legal and identity-preserving; a conduit that carried no realized_by in 2.0.0 keeps its identifier under 3.0.0."
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|