kibi-core 0.7.0 → 0.8.1
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/package.json +1 -1
- package/schema/entities.pl +16 -0
- package/schema/relationships.pl +2 -0
- package/schema/validation.pl +59 -31
- package/src/checks.pl +419 -6
- package/src/kb.pl +22 -1
- package/src/logic_ir.pl +629 -0
- package/src/sparql_client.pl +23 -1
- package/src/status.pl +9 -0
package/package.json
CHANGED
package/schema/entities.pl
CHANGED
|
@@ -29,6 +29,8 @@ entity_property(_, severity, atom).
|
|
|
29
29
|
entity_property(_, links, list).
|
|
30
30
|
entity_property(_, text_ref, uri).
|
|
31
31
|
entity_property(_, sourceFile, uri).
|
|
32
|
+
entity_property(req, logic_claims, list).
|
|
33
|
+
entity_property(req, semantic_inventory, list).
|
|
32
34
|
|
|
33
35
|
% Typed fact fields - only valid for fact entities
|
|
34
36
|
entity_property(fact, fact_kind, atom).
|
|
@@ -47,6 +49,8 @@ entity_property(fact, closed_world, boolean).
|
|
|
47
49
|
entity_property(fact, valid_from, datetime).
|
|
48
50
|
entity_property(fact, valid_to, datetime).
|
|
49
51
|
entity_property(fact, canonical_key, string).
|
|
52
|
+
entity_property(fact, claim_key, string).
|
|
53
|
+
entity_property(fact, claim_text, string).
|
|
50
54
|
entity_property(fact, predicate_name, string).
|
|
51
55
|
entity_property(fact, predicate_namespace, string).
|
|
52
56
|
entity_property(fact, predicate_arity, integer).
|
|
@@ -56,6 +60,16 @@ entity_property(fact, argument_descriptions, list).
|
|
|
56
60
|
entity_property(fact, aliases, list).
|
|
57
61
|
entity_property(fact, examples, list).
|
|
58
62
|
entity_property(fact, predicate_args, list).
|
|
63
|
+
entity_property(fact, rule_ir, string).
|
|
64
|
+
entity_property(fact, rule_hash, string).
|
|
65
|
+
% Rule schema references are JSON strings at the public boundary, but the
|
|
66
|
+
% Prolog peer represents entity identifiers as atoms. Accept both forms so
|
|
67
|
+
% decoded rule facts validate without losing the typed reference.
|
|
68
|
+
entity_property(fact, rule_schema_id, atom_or_string).
|
|
69
|
+
entity_property(fact, rule_name, string).
|
|
70
|
+
entity_property(fact, semantic_key, string).
|
|
71
|
+
entity_property(fact, claim_span_start, integer).
|
|
72
|
+
entity_property(fact, claim_span_end, integer).
|
|
59
73
|
|
|
60
74
|
% Typed symbol metadata fields - only valid for symbol entities
|
|
61
75
|
entity_property(symbol, symbol_role, atom).
|
|
@@ -80,6 +94,8 @@ optional_property(Type, priority) :- entity_type(Type).
|
|
|
80
94
|
optional_property(Type, severity) :- entity_type(Type).
|
|
81
95
|
optional_property(Type, links) :- entity_type(Type).
|
|
82
96
|
optional_property(Type, text_ref) :- entity_type(Type).
|
|
97
|
+
optional_property(req, logic_claims).
|
|
98
|
+
optional_property(req, semantic_inventory).
|
|
83
99
|
optional_property(test, verification_scope).
|
|
84
100
|
optional_property(test, verification_perspective).
|
|
85
101
|
|
package/schema/relationships.pl
CHANGED
|
@@ -19,6 +19,7 @@ relationship_type(supersedes).
|
|
|
19
19
|
relationship_type(constrains).
|
|
20
20
|
relationship_type(requires_property).
|
|
21
21
|
relationship_type(requires_predicate).
|
|
22
|
+
relationship_type(requires_rule).
|
|
22
23
|
|
|
23
24
|
% valid_relationship(RelType, FromType, ToType).
|
|
24
25
|
valid_relationship(depends_on, req, req).
|
|
@@ -40,6 +41,7 @@ valid_relationship(consumes, symbol, event).
|
|
|
40
41
|
valid_relationship(constrains, req, fact).
|
|
41
42
|
valid_relationship(requires_property, req, fact).
|
|
42
43
|
valid_relationship(requires_predicate, req, fact).
|
|
44
|
+
valid_relationship(requires_rule, req, fact).
|
|
43
45
|
|
|
44
46
|
%% supersedes(+NewAdrId, +OldAdrId)
|
|
45
47
|
%% NewAdrId is the decision that replaces OldAdrId.
|
package/schema/validation.pl
CHANGED
|
@@ -42,6 +42,7 @@ validate_property_type(Type, Prop, Value) :-
|
|
|
42
42
|
% check_kind(Kind, Value) succeeds if Value matches Kind
|
|
43
43
|
check_kind(atom, V) :- atom(V).
|
|
44
44
|
check_kind(string, V) :- string(V).
|
|
45
|
+
check_kind(atom_or_string, V) :- atom(V) ; string(V).
|
|
45
46
|
check_kind(datetime, V) :- string(V). % accept ISO strings for now
|
|
46
47
|
check_kind(list, V) :- is_list(V).
|
|
47
48
|
check_kind(uri, V) :- string(V).
|
|
@@ -59,17 +60,24 @@ validate_entity_shape(fact, Props) :-
|
|
|
59
60
|
!,
|
|
60
61
|
valid_optional_fact_enums(Props),
|
|
61
62
|
valid_polarity_in_props(Props),
|
|
63
|
+
valid_claim_provenance(Props),
|
|
62
64
|
( memberchk(fact_kind=RawKind, Props) -> validate_fact_shape(RawKind, Props) ; true ).
|
|
63
65
|
validate_entity_shape(test, Props) :-
|
|
64
66
|
!,
|
|
65
67
|
valid_optional_test_enums(Props),
|
|
66
68
|
forall(member(Key=_, Props), \+ is_fact_only_field(Key)).
|
|
69
|
+
validate_entity_shape(req, Props) :-
|
|
70
|
+
!,
|
|
71
|
+
forall(member(Key=_, Props), \+ is_fact_only_field(Key)),
|
|
72
|
+
forall(member(Key=_, Props), \+ is_test_only_field(Key)).
|
|
67
73
|
validate_entity_shape(Type, Props) :-
|
|
68
74
|
Type \= fact,
|
|
69
75
|
Type \= test,
|
|
76
|
+
Type \= req,
|
|
70
77
|
% Non-fact/non-test entities cannot have type-specific fields
|
|
71
78
|
forall(member(Key=_, Props), \+ is_fact_only_field(Key)),
|
|
72
|
-
forall(member(Key=_, Props), \+ is_test_only_field(Key))
|
|
79
|
+
forall(member(Key=_, Props), \+ is_test_only_field(Key)),
|
|
80
|
+
forall(member(Key=_, Props), Key \= logic_claims).
|
|
73
81
|
|
|
74
82
|
% is_fact_only_field(+Key) - true if Key is a fact-specific field
|
|
75
83
|
is_fact_only_field(fact_kind).
|
|
@@ -88,6 +96,8 @@ is_fact_only_field(closed_world).
|
|
|
88
96
|
is_fact_only_field(valid_from).
|
|
89
97
|
is_fact_only_field(valid_to).
|
|
90
98
|
is_fact_only_field(canonical_key).
|
|
99
|
+
is_fact_only_field(claim_key).
|
|
100
|
+
is_fact_only_field(claim_text).
|
|
91
101
|
is_fact_only_field(predicate_name).
|
|
92
102
|
is_fact_only_field(predicate_namespace).
|
|
93
103
|
is_fact_only_field(predicate_arity).
|
|
@@ -97,6 +107,13 @@ is_fact_only_field(argument_descriptions).
|
|
|
97
107
|
is_fact_only_field(aliases).
|
|
98
108
|
is_fact_only_field(examples).
|
|
99
109
|
is_fact_only_field(predicate_args).
|
|
110
|
+
is_fact_only_field(rule_ir).
|
|
111
|
+
is_fact_only_field(rule_hash).
|
|
112
|
+
is_fact_only_field(rule_schema_id).
|
|
113
|
+
is_fact_only_field(rule_name).
|
|
114
|
+
is_fact_only_field(semantic_key).
|
|
115
|
+
is_fact_only_field(claim_span_start).
|
|
116
|
+
is_fact_only_field(claim_span_end).
|
|
100
117
|
|
|
101
118
|
% is_test_only_field(+Key) - true if Key is a test-specific field
|
|
102
119
|
is_test_only_field(verification_scope).
|
|
@@ -106,7 +123,7 @@ is_test_only_field(verification_perspective).
|
|
|
106
123
|
validate_fact_shape(subject, Props) :-
|
|
107
124
|
memberchk(subject_key=_Val, Props),
|
|
108
125
|
valid_optional_fact_enums(Props),
|
|
109
|
-
valid_strict_polarity_in_props(Props)
|
|
126
|
+
valid_strict_polarity_in_props(Props), !.
|
|
110
127
|
validate_fact_shape(property_value, Props) :-
|
|
111
128
|
memberchk(subject_key=_Subject, Props),
|
|
112
129
|
memberchk(property_key=_Property, Props),
|
|
@@ -117,14 +134,14 @@ validate_fact_shape(property_value, Props) :-
|
|
|
117
134
|
exactly_one_value_field(Props),
|
|
118
135
|
value_type_matches_field(VT, Props),
|
|
119
136
|
valid_optional_fact_enums(Props),
|
|
120
|
-
valid_strict_polarity_in_props(Props)
|
|
137
|
+
valid_strict_polarity_in_props(Props), !.
|
|
121
138
|
validate_fact_shape(observation, Props) :-
|
|
122
139
|
valid_optional_fact_enums(Props),
|
|
123
|
-
valid_polarity_in_props(Props)
|
|
140
|
+
valid_polarity_in_props(Props), !.
|
|
124
141
|
validate_fact_shape(meta, Props) :-
|
|
125
142
|
% Meta facts are allowed but don't require full strict property tuple yet
|
|
126
143
|
valid_optional_fact_enums(Props),
|
|
127
|
-
valid_polarity_in_props(Props)
|
|
144
|
+
valid_polarity_in_props(Props), !.
|
|
128
145
|
validate_fact_shape(predicate_schema, Props) :-
|
|
129
146
|
memberchk(predicate_name=_Name, Props),
|
|
130
147
|
memberchk(predicate_arity=Arity, Props),
|
|
@@ -134,32 +151,39 @@ validate_fact_shape(predicate_schema, Props) :-
|
|
|
134
151
|
same_length(ArgumentNames, ArgumentTypes),
|
|
135
152
|
length(ArgumentNames, Arity),
|
|
136
153
|
valid_optional_fact_enums(Props),
|
|
137
|
-
valid_polarity_in_props(Props)
|
|
154
|
+
valid_polarity_in_props(Props), !.
|
|
138
155
|
validate_fact_shape(predicate, Props) :-
|
|
139
156
|
memberchk(predicate_name=_Name, Props),
|
|
140
157
|
memberchk(predicate_args=Args, Props),
|
|
141
158
|
Args \= [],
|
|
142
159
|
memberchk(canonical_key=_CanonicalKey, Props),
|
|
143
160
|
valid_optional_fact_enums(Props),
|
|
144
|
-
valid_predicate_polarity_in_props(Props)
|
|
161
|
+
valid_predicate_polarity_in_props(Props), !.
|
|
162
|
+
validate_fact_shape(rule_schema, Props) :-
|
|
163
|
+
memberchk(rule_name=_Name, Props),
|
|
164
|
+
memberchk(argument_names=ArgumentNames, Props),
|
|
165
|
+
memberchk(argument_types=ArgumentTypes, Props),
|
|
166
|
+
same_length(ArgumentNames, ArgumentTypes),
|
|
167
|
+
valid_optional_fact_enums(Props),
|
|
168
|
+
valid_polarity_in_props(Props), !.
|
|
169
|
+
validate_fact_shape(rule, Props) :-
|
|
170
|
+
memberchk(rule_ir=RuleIr, Props),
|
|
171
|
+
nonempty_claim_value(RuleIr),
|
|
172
|
+
memberchk(rule_hash=_Hash, Props),
|
|
173
|
+
memberchk(rule_schema_id=_SchemaId, Props),
|
|
174
|
+
memberchk(semantic_key=_SemanticKey, Props),
|
|
175
|
+
valid_optional_fact_enums(Props),
|
|
176
|
+
valid_polarity_in_props(Props), !.
|
|
145
177
|
validate_fact_shape(Kind, _Props) :-
|
|
146
178
|
% Unknown fact_kind values fail validation
|
|
147
|
-
\+ memberchk(Kind, [subject, property_value, observation, meta, predicate_schema, predicate]),
|
|
179
|
+
\+ memberchk(Kind, [subject, property_value, observation, meta, predicate_schema, predicate, rule_schema, rule]),
|
|
148
180
|
fail.
|
|
149
181
|
|
|
150
182
|
% valid_operator(+Op)
|
|
151
|
-
valid_operator(eq)
|
|
152
|
-
valid_operator(neq).
|
|
153
|
-
valid_operator(lt).
|
|
154
|
-
valid_operator(lte).
|
|
155
|
-
valid_operator(gt).
|
|
156
|
-
valid_operator(gte).
|
|
183
|
+
valid_operator(Op) :- memberchk(Op, [eq, neq, lt, lte, gt, gte]), !.
|
|
157
184
|
|
|
158
185
|
% valid_value_type(+VT)
|
|
159
|
-
valid_value_type(string)
|
|
160
|
-
valid_value_type(int).
|
|
161
|
-
valid_value_type(number).
|
|
162
|
-
valid_value_type(bool).
|
|
186
|
+
valid_value_type(ValueType) :- memberchk(ValueType, [string, int, number, bool]), !.
|
|
163
187
|
|
|
164
188
|
% valid_polarity_in_props(+Props)
|
|
165
189
|
% Validates polarity if present; succeeds if no polarity in props
|
|
@@ -172,6 +196,18 @@ valid_strict_polarity_in_props(Props) :-
|
|
|
172
196
|
valid_predicate_polarity_in_props(Props) :-
|
|
173
197
|
( memberchk(polarity=P, Props) -> valid_predicate_polarity(P) ; true ).
|
|
174
198
|
|
|
199
|
+
% claim_key and claim_text form one auditable provenance pair.
|
|
200
|
+
valid_claim_provenance(Props) :-
|
|
201
|
+
( memberchk(claim_key=Key, Props)
|
|
202
|
+
-> memberchk(claim_text=Text, Props),
|
|
203
|
+
nonempty_claim_value(Key),
|
|
204
|
+
nonempty_claim_value(Text)
|
|
205
|
+
; \+ memberchk(claim_text=_, Props)
|
|
206
|
+
).
|
|
207
|
+
|
|
208
|
+
nonempty_claim_value(Value) :- string(Value), Value \= "", !.
|
|
209
|
+
nonempty_claim_value(Value) :- atom(Value), Value \= '', !.
|
|
210
|
+
|
|
175
211
|
% valid_optional_fact_enums(+Props)
|
|
176
212
|
% Validates enum-typed fact fields whenever they are present
|
|
177
213
|
valid_optional_fact_enums(Props) :-
|
|
@@ -185,25 +221,17 @@ valid_optional_test_enums(Props) :-
|
|
|
185
221
|
( memberchk(verification_perspective=Perspective, Props) -> valid_verification_perspective(Perspective) ; true ).
|
|
186
222
|
|
|
187
223
|
% valid_polarity(+P)
|
|
188
|
-
valid_polarity(require)
|
|
189
|
-
valid_polarity(forbid).
|
|
190
|
-
valid_polarity(assert).
|
|
191
|
-
valid_polarity(deny).
|
|
224
|
+
valid_polarity(Polarity) :- memberchk(Polarity, [require, forbid, assert, deny]), !.
|
|
192
225
|
|
|
193
|
-
valid_strict_polarity(require)
|
|
194
|
-
valid_strict_polarity(forbid).
|
|
226
|
+
valid_strict_polarity(Polarity) :- memberchk(Polarity, [require, forbid]), !.
|
|
195
227
|
|
|
196
|
-
valid_predicate_polarity(assert)
|
|
197
|
-
valid_predicate_polarity(deny).
|
|
228
|
+
valid_predicate_polarity(Polarity) :- memberchk(Polarity, [assert, deny]), !.
|
|
198
229
|
|
|
199
230
|
% valid_verification_scope(+Scope)
|
|
200
|
-
valid_verification_scope(unit)
|
|
201
|
-
valid_verification_scope(integration).
|
|
202
|
-
valid_verification_scope(end_to_end).
|
|
231
|
+
valid_verification_scope(Scope) :- memberchk(Scope, [unit, integration, end_to_end]), !.
|
|
203
232
|
|
|
204
233
|
% valid_verification_perspective(+Perspective)
|
|
205
|
-
valid_verification_perspective(internal)
|
|
206
|
-
valid_verification_perspective(consumer).
|
|
234
|
+
valid_verification_perspective(Perspective) :- memberchk(Perspective, [internal, consumer]), !.
|
|
207
235
|
|
|
208
236
|
% exactly_one_value_field(+Props)
|
|
209
237
|
exactly_one_value_field(Props) :-
|