kibi-core 0.9.1 → 0.11.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/package.json +6 -4
- package/schema/entities.pl +3 -0
- package/schema/relationships.pl +1 -0
- package/schema/validation.pl +1 -0
- package/src/checks.pl +123 -5
- package/src/discovery.pl +2 -1
- package/src/kb.pl +1087 -24
- package/src/logic_ir.pl +1 -1
- package/src/requirement_proof.pl +306 -49
- package/src/status.pl +161 -34
package/package.json
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kibi-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Core Prolog modules and RDF graph logic for Kibi",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"engines": {
|
|
8
|
-
"node": ">=18"
|
|
9
|
-
"bun": ">=1.0"
|
|
8
|
+
"node": ">=18"
|
|
10
9
|
},
|
|
11
10
|
"main": "./src/kb.pl",
|
|
12
|
-
"files": [
|
|
11
|
+
"files": [
|
|
12
|
+
"src/**/*.pl",
|
|
13
|
+
"schema/**/*.pl"
|
|
14
|
+
],
|
|
13
15
|
"license": "AGPL-3.0-or-later",
|
|
14
16
|
"author": "Piotr Franczyk",
|
|
15
17
|
"repository": {
|
package/schema/entities.pl
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
:- module(kibi_entities, [entity_type/1, entity_property/3, required_property/2, optional_property/2]).
|
|
4
4
|
|
|
5
5
|
% Entity types
|
|
6
|
+
% implements REQ-004
|
|
6
7
|
entity_type(req).
|
|
7
8
|
entity_type(scenario).
|
|
8
9
|
entity_type(test).
|
|
@@ -87,6 +88,7 @@ entity_property(symbol, sourceEndColumn, integer).
|
|
|
87
88
|
% Typed test verification fields - only valid for test entities
|
|
88
89
|
entity_property(test, verification_scope, atom).
|
|
89
90
|
entity_property(test, verification_perspective, atom).
|
|
91
|
+
entity_property(test, verification_contract, list_or_json).
|
|
90
92
|
entity_property(test, verification_receipts, string).
|
|
91
93
|
|
|
92
94
|
% Required properties for all entity types
|
|
@@ -113,6 +115,7 @@ optional_property(req, semantic_source_hash).
|
|
|
113
115
|
optional_property(req, semantic_inventory).
|
|
114
116
|
optional_property(test, verification_scope).
|
|
115
117
|
optional_property(test, verification_perspective).
|
|
118
|
+
optional_property(test, verification_contract).
|
|
116
119
|
optional_property(test, verification_receipts).
|
|
117
120
|
|
|
118
121
|
% Documentation helpers
|
package/schema/relationships.pl
CHANGED
package/schema/validation.pl
CHANGED
|
@@ -119,6 +119,7 @@ is_fact_only_field(claim_span_end).
|
|
|
119
119
|
% is_test_only_field(+Key) - true if Key is a test-specific field
|
|
120
120
|
is_test_only_field(verification_scope).
|
|
121
121
|
is_test_only_field(verification_perspective).
|
|
122
|
+
is_test_only_field(verification_contract).
|
|
122
123
|
is_test_only_field(verification_receipts).
|
|
123
124
|
|
|
124
125
|
% validate_fact_shape(+Kind, +Props)
|
package/src/checks.pl
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
:- module(checks, [
|
|
7
7
|
check_all/1, % Returns all violations as a dict
|
|
8
8
|
check_all_json/1, % Returns all violations as JSON string
|
|
9
|
+
check_selected_json/2, % Returns only selected rule violations as JSON
|
|
9
10
|
check_must_priority_coverage/1, % Returns list of must-priority violations
|
|
10
11
|
check_symbol_coverage/1, % Returns list of uncovered symbols
|
|
11
12
|
check_symbol_traceability/2, % Returns list of symbols lacking requirement traceability (ReqAdr option)
|
|
@@ -14,6 +15,7 @@
|
|
|
14
15
|
check_required_fields/1, % Returns list of missing required field violations
|
|
15
16
|
check_deprecated_adrs/1, % Returns list of deprecated ADR violations
|
|
16
17
|
check_domain_contradictions/1, % Returns list of contradiction violations
|
|
18
|
+
check_domain_contradictions_and_witnesses/2,
|
|
17
19
|
check_domain_contradiction_witnesses/1,
|
|
18
20
|
check_strict_fact_shape/1, % Returns list of malformed strict fact violations
|
|
19
21
|
check_strict_req_fact_pairing/1,% Returns list of malformed strict req/fact pairing violations
|
|
@@ -591,6 +593,15 @@ check_domain_contradictions(Violations) :-
|
|
|
591
593
|
check_domain_contradiction_witnesses(Witnesses),
|
|
592
594
|
maplist(contradiction_witness_violation, Witnesses, Violations).
|
|
593
595
|
|
|
596
|
+
%% check_domain_contradictions_and_witnesses(-Violations, -Witnesses)
|
|
597
|
+
% Compute the contradiction witness graph once when a caller needs both the
|
|
598
|
+
% report violations and their exact evidence. The existing one-result
|
|
599
|
+
% predicates remain unchanged; this paired form avoids duplicate work in
|
|
600
|
+
% proof contexts without weakening any contradiction checks.
|
|
601
|
+
check_domain_contradictions_and_witnesses(Violations, Witnesses) :-
|
|
602
|
+
check_domain_contradiction_witnesses(Witnesses),
|
|
603
|
+
maplist(contradiction_witness_violation, Witnesses, Violations).
|
|
604
|
+
|
|
594
605
|
%% check_domain_contradiction_witnesses(-Witnesses)
|
|
595
606
|
% Exact, JSON-safe evidence for every strict-property, ground-predicate, and
|
|
596
607
|
% safe-rule contradiction result. Rule overlap that cannot be proven or
|
|
@@ -989,9 +1000,11 @@ predicate_verifiability_kind_label(Kind, Label) :-
|
|
|
989
1000
|
|
|
990
1001
|
%% check_logic_coverage(-Violations)
|
|
991
1002
|
% Validates explicitly declared atomic requirement claim manifests. Legacy
|
|
992
|
-
% requirements without logic_claims remain eligible for gradual backfill
|
|
993
|
-
%
|
|
994
|
-
%
|
|
1003
|
+
% requirements without logic_claims remain eligible for gradual backfill. A
|
|
1004
|
+
% modeled proposition must be grounded exactly once; ambiguous, ontology-gap,
|
|
1005
|
+
% and missing propositions remain explicit unresolved inventory states and are
|
|
1006
|
+
% not required to have a ground fact (missing is reported by semantic
|
|
1007
|
+
% completeness).
|
|
995
1008
|
check_logic_coverage(Violations) :-
|
|
996
1009
|
findall(Violation, logic_coverage_violation(Violation), Violations0),
|
|
997
1010
|
sort(Violations0, Violations).
|
|
@@ -1006,6 +1019,7 @@ logic_coverage_violation(violation(
|
|
|
1006
1019
|
kb:current_req(ReqId),
|
|
1007
1020
|
requirement_logic_claims(ReqId, ClaimKeys),
|
|
1008
1021
|
member(ClaimKey, ClaimKeys),
|
|
1022
|
+
claim_requires_grounding(ReqId, ClaimKey),
|
|
1009
1023
|
\+ grounded_requirement_claim(ReqId, ClaimKey),
|
|
1010
1024
|
format(
|
|
1011
1025
|
string(Description),
|
|
@@ -1014,6 +1028,24 @@ logic_coverage_violation(violation(
|
|
|
1014
1028
|
),
|
|
1015
1029
|
violation_source(ReqId, req, Source).
|
|
1016
1030
|
|
|
1031
|
+
logic_coverage_violation(violation(
|
|
1032
|
+
'logic-coverage',
|
|
1033
|
+
ReqId,
|
|
1034
|
+
Description,
|
|
1035
|
+
"Keep ontology gaps, ambiguities, and missing interpretations unresolved; only modeled propositions may have logical ground facts",
|
|
1036
|
+
Source
|
|
1037
|
+
)) :-
|
|
1038
|
+
kb:current_req(ReqId),
|
|
1039
|
+
requirement_inventory_status(ReqId, ClaimKey, Status),
|
|
1040
|
+
memberchk(Status, [ambiguous, ontology_gap, missing]),
|
|
1041
|
+
grounded_requirement_claim(ReqId, ClaimKey),
|
|
1042
|
+
format(
|
|
1043
|
+
string(Description),
|
|
1044
|
+
"Requirement grounds unresolved ~w proposition ~w",
|
|
1045
|
+
[Status, ClaimKey]
|
|
1046
|
+
),
|
|
1047
|
+
violation_source(ReqId, req, Source).
|
|
1048
|
+
|
|
1017
1049
|
logic_coverage_violation(violation(
|
|
1018
1050
|
'logic-coverage',
|
|
1019
1051
|
ReqId,
|
|
@@ -1076,6 +1108,28 @@ requirement_logic_claims(ReqId, ClaimKeys) :-
|
|
|
1076
1108
|
memberchk(logic_claims=RawClaimKeys, Props),
|
|
1077
1109
|
kb:normalize_term_atom_list(RawClaimKeys, ClaimKeys).
|
|
1078
1110
|
|
|
1111
|
+
claim_requires_grounding(ReqId, ClaimKey) :-
|
|
1112
|
+
requirement_inventory_status(ReqId, ClaimKey, modeled),
|
|
1113
|
+
!.
|
|
1114
|
+
claim_requires_grounding(ReqId, ClaimKey) :-
|
|
1115
|
+
\+ requirement_inventory_status(ReqId, ClaimKey, _).
|
|
1116
|
+
|
|
1117
|
+
requirement_inventory_status(ReqId, ClaimKey, Status) :-
|
|
1118
|
+
kb_entity(ReqId, req, Props),
|
|
1119
|
+
memberchk(semantic_inventory=RawInventory, Props),
|
|
1120
|
+
inventory_entries(RawInventory, Entries),
|
|
1121
|
+
member(Entry, Entries),
|
|
1122
|
+
checks_inventory_entry_field(Entry, claim_key, RawClaimKey),
|
|
1123
|
+
kb:normalize_term_atom(RawClaimKey, ClaimKey),
|
|
1124
|
+
inventory_entry_status(Entry, Status).
|
|
1125
|
+
|
|
1126
|
+
checks_inventory_entry_field(Entry, Key, Value) :-
|
|
1127
|
+
is_dict(Entry),
|
|
1128
|
+
get_dict(Key, Entry, Value).
|
|
1129
|
+
checks_inventory_entry_field(Entry, Key, Value) :-
|
|
1130
|
+
is_list(Entry),
|
|
1131
|
+
memberchk(Key=Value, Entry).
|
|
1132
|
+
|
|
1079
1133
|
grounded_requirement_claim(ReqId, ClaimKey) :-
|
|
1080
1134
|
grounded_requirement_claim_fact(ReqId, ClaimKey, _FactId).
|
|
1081
1135
|
|
|
@@ -1222,13 +1276,15 @@ rule_verifiability_description(Props, FactId, Description) :-
|
|
|
1222
1276
|
rule_verifiability_description(Props, FactId, Description) :-
|
|
1223
1277
|
memberchk(fact_kind=RawKind, Props),
|
|
1224
1278
|
normalize_term_atom(RawKind, rule),
|
|
1225
|
-
memberchk(rule_schema_id=
|
|
1279
|
+
memberchk(rule_schema_id=RawSchemaId, Props),
|
|
1280
|
+
normalize_term_atom(RawSchemaId, SchemaId),
|
|
1226
1281
|
\+ kb_entity(SchemaId, fact, _),
|
|
1227
1282
|
format(string(Description), "Rule fact ~w references missing rule schema ~w", [FactId, SchemaId]).
|
|
1228
1283
|
rule_verifiability_description(Props, FactId, Description) :-
|
|
1229
1284
|
memberchk(fact_kind=RawKind, Props),
|
|
1230
1285
|
normalize_term_atom(RawKind, rule),
|
|
1231
|
-
memberchk(rule_schema_id=
|
|
1286
|
+
memberchk(rule_schema_id=RawSchemaId, Props),
|
|
1287
|
+
normalize_term_atom(RawSchemaId, SchemaId),
|
|
1232
1288
|
kb_entity(SchemaId, fact, SchemaProps),
|
|
1233
1289
|
\+ valid_rule_schema_props(SchemaProps),
|
|
1234
1290
|
format(string(Description), "Rule fact ~w references ~w, which is not a rule_schema fact", [FactId, SchemaId]).
|
|
@@ -1286,6 +1342,10 @@ inventory_entries(Raw, Entries) :-
|
|
|
1286
1342
|
catch(atom_json_dict(Raw, JsonEntries, [value_string_as(string)]), _, fail),
|
|
1287
1343
|
is_list(JsonEntries)
|
|
1288
1344
|
-> Entries = JsonEntries
|
|
1345
|
+
; (atom(Raw) ; string(Raw)),
|
|
1346
|
+
catch(term_string(PrologEntries, Raw), _, fail),
|
|
1347
|
+
is_list(PrologEntries)
|
|
1348
|
+
-> Entries = PrologEntries
|
|
1289
1349
|
; Entries = []
|
|
1290
1350
|
).
|
|
1291
1351
|
|
|
@@ -1341,6 +1401,64 @@ check_all_json(JsonString) :-
|
|
|
1341
1401
|
JsonString
|
|
1342
1402
|
).
|
|
1343
1403
|
|
|
1404
|
+
%% check_selected_json(+Rules, -JsonString)
|
|
1405
|
+
% Run only the named aggregated checks. This is intentionally separate from
|
|
1406
|
+
% check_all/1 so focused diagnostics cannot evaluate unrelated rule queries.
|
|
1407
|
+
check_selected_json(Rules, JsonString) :-
|
|
1408
|
+
check_selected(Rules, ViolationsDict),
|
|
1409
|
+
violations_dict_to_json(ViolationsDict, JsonDict),
|
|
1410
|
+
with_output_to_string(
|
|
1411
|
+
json_write_dict(current_output, JsonDict, [width(0)]),
|
|
1412
|
+
JsonString
|
|
1413
|
+
).
|
|
1414
|
+
|
|
1415
|
+
check_selected(Rules, _{
|
|
1416
|
+
must_priority_coverage: MustPriority,
|
|
1417
|
+
symbol_coverage: SymbolCoverage,
|
|
1418
|
+
symbol_traceability: SymbolTraceability,
|
|
1419
|
+
no_dangling_refs: DanglingRefs,
|
|
1420
|
+
no_cycles: Cycles,
|
|
1421
|
+
required_fields: RequiredFields,
|
|
1422
|
+
deprecated_adr_no_successor: DeprecatedADRs,
|
|
1423
|
+
domain_contradictions: Contradictions,
|
|
1424
|
+
strict_fact_shape: StrictFactShape,
|
|
1425
|
+
strict_req_fact_pairing: StrictReqFactPairing,
|
|
1426
|
+
strict_readiness: StrictReadiness,
|
|
1427
|
+
predicate_verifiability: PredicateVerifiability,
|
|
1428
|
+
logic_coverage: LogicCoverage,
|
|
1429
|
+
rule_safety: RuleSafety,
|
|
1430
|
+
rule_verifiability: RuleVerifiability,
|
|
1431
|
+
semantic_completeness: SemanticCompleteness
|
|
1432
|
+
}) :-
|
|
1433
|
+
selected_rule(Rules, 'must-priority-coverage', check_must_priority_coverage, MustPriority),
|
|
1434
|
+
selected_rule(Rules, 'symbol-coverage', check_symbol_coverage, SymbolCoverage),
|
|
1435
|
+
selected_rule_with_options(Rules, 'symbol-traceability', check_symbol_traceability, SymbolTraceability),
|
|
1436
|
+
selected_rule(Rules, 'no-dangling-refs', check_no_dangling_refs, DanglingRefs),
|
|
1437
|
+
selected_rule(Rules, 'no-cycles', check_no_cycles, Cycles),
|
|
1438
|
+
selected_rule(Rules, 'required-fields', check_required_fields, RequiredFields),
|
|
1439
|
+
selected_rule(Rules, 'deprecated-adr-no-successor', check_deprecated_adrs, DeprecatedADRs),
|
|
1440
|
+
selected_rule(Rules, 'domain-contradictions', check_domain_contradictions, Contradictions),
|
|
1441
|
+
selected_rule(Rules, 'strict-fact-shape', check_strict_fact_shape, StrictFactShape),
|
|
1442
|
+
selected_rule(Rules, 'strict-req-fact-pairing', check_strict_req_fact_pairing, StrictReqFactPairing),
|
|
1443
|
+
selected_rule(Rules, 'strict-readiness', check_strict_readiness, StrictReadiness),
|
|
1444
|
+
selected_rule(Rules, 'predicate-verifiability', check_predicate_verifiability, PredicateVerifiability),
|
|
1445
|
+
selected_rule(Rules, 'logic-coverage', check_logic_coverage, LogicCoverage),
|
|
1446
|
+
selected_rule(Rules, 'rule-safety', check_rule_safety, RuleSafety),
|
|
1447
|
+
selected_rule(Rules, 'rule-verifiability', check_rule_verifiability, RuleVerifiability),
|
|
1448
|
+
selected_rule(Rules, 'semantic-completeness', check_semantic_completeness, SemanticCompleteness).
|
|
1449
|
+
|
|
1450
|
+
selected_rule(Rules, Name, Goal, Violations) :-
|
|
1451
|
+
( memberchk(Name, Rules)
|
|
1452
|
+
-> call(Goal, Violations)
|
|
1453
|
+
; Violations = []
|
|
1454
|
+
).
|
|
1455
|
+
|
|
1456
|
+
selected_rule_with_options(Rules, Name, Goal, Violations) :-
|
|
1457
|
+
( memberchk(Name, Rules)
|
|
1458
|
+
-> call(Goal, false, Violations)
|
|
1459
|
+
; Violations = []
|
|
1460
|
+
).
|
|
1461
|
+
|
|
1344
1462
|
%% check_all_json_with_options(-JsonString, +RequireAdr)
|
|
1345
1463
|
% Returns all violations as JSON string with options.
|
|
1346
1464
|
% RequireAdr: if true, symbol-traceability also requires ADR constraints.
|
package/src/discovery.pl
CHANGED
|
@@ -143,7 +143,7 @@ coverage_rows(type, _Tags, _IncludePassing, _IncludeTransitive, _VerificationSna
|
|
|
143
143
|
requirement_coverage_row(Tags, IncludeTransitive, ProofContext, Row) :-
|
|
144
144
|
kb_entity(Id, req, Props),
|
|
145
145
|
matches_tags(Tags, Props),
|
|
146
|
-
entity_title_status_source(Props, Title, Status,
|
|
146
|
+
entity_title_status_source(Props, Title, Status, Source),
|
|
147
147
|
entity_priority(Props, Priority),
|
|
148
148
|
count_distinct_targets(specified_by, Id, source, ScenarioCount),
|
|
149
149
|
requirement_test_count(Id, TestCount),
|
|
@@ -156,6 +156,7 @@ requirement_coverage_row(Tags, IncludeTransitive, ProofContext, Row) :-
|
|
|
156
156
|
type: req,
|
|
157
157
|
title: Title,
|
|
158
158
|
status: Status,
|
|
159
|
+
source: Source,
|
|
159
160
|
priority: Priority,
|
|
160
161
|
scenarioCount: ScenarioCount,
|
|
161
162
|
testCount: TestCount,
|