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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kibi-core",
3
- "version": "0.7.0",
3
+ "version": "0.8.1",
4
4
  "private": false,
5
5
  "description": "Core Prolog modules and RDF graph logic for Kibi",
6
6
  "type": "module",
@@ -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
 
@@ -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.
@@ -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) :-