kibi-core 0.16.0 → 0.17.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.16.0",
3
+ "version": "0.17.1",
4
4
  "private": false,
5
5
  "description": "Core Prolog modules and RDF graph logic for Kibi",
6
6
  "type": "module",
package/src/checks.pl CHANGED
@@ -41,6 +41,7 @@
41
41
  check_rule_safety/1,
42
42
  check_rule_verifiability/1,
43
43
  check_semantic_completeness/1,
44
+ check_related_requirement_unmodeled/1,
44
45
  check_req_status_vocabulary/1,
45
46
  check_entity_id_style/1,
46
47
  check_domain_redundancy/1,
@@ -114,6 +115,7 @@ check_all(ViolationsDict) :-
114
115
  check_rule_safety(RuleSafety),
115
116
  check_rule_verifiability(RuleVerifiability),
116
117
  check_semantic_completeness(SemanticCompleteness),
118
+ check_related_requirement_unmodeled(RelatedRequirementUnmodeled),
117
119
  check_req_status_vocabulary(ReqStatusVocabulary),
118
120
  check_proof_contract_symbols(ProofContractSymbols),
119
121
  check_entity_id_style(EntityIdStyle),
@@ -148,6 +150,7 @@ check_all(ViolationsDict) :-
148
150
  rule_safety: RuleSafety,
149
151
  rule_verifiability: RuleVerifiability,
150
152
  semantic_completeness: SemanticCompleteness,
153
+ related_requirement_unmodeled: RelatedRequirementUnmodeled,
151
154
  req_status_vocabulary: ReqStatusVocabulary,
152
155
  proof_contract_symbols: ProofContractSymbols,
153
156
  entity_id_style: EntityIdStyle,
@@ -2763,7 +2766,7 @@ strict_req_fact_pairing_violation(violation(
2763
2766
  strict_req_fact_pairing_issue(
2764
2767
  ReqId,
2765
2768
  Description,
2766
- "Add a property_value fact via requires_property for the same subject_key"
2769
+ "Add a property_value fact via requires_property for the same subject_key, or link requires_predicate to a fact_kind: predicate fact whose first argument is that subject_key"
2767
2770
  ) :-
2768
2771
  kb:current_req(ReqId),
2769
2772
  kb_relationship(constrains, ReqId, SubjectFactId),
@@ -2783,9 +2786,10 @@ strict_req_fact_pairing_issue(
2783
2786
  _ValidFrom,
2784
2787
  _ValidTo
2785
2788
  ),
2789
+ \+ strict_req_predicate_grounds_subject(ReqId, SubjectKey),
2786
2790
  format(
2787
2791
  string(Description),
2788
- "Requirement constrains ~w (~w) but has no matching strict requires_property fact",
2792
+ "Requirement constrains ~w (~w) but has no matching strict requires_property fact and no requires_predicate fact about that subject",
2789
2793
  [SubjectFactId, SubjectKey]
2790
2794
  ).
2791
2795
 
@@ -2867,13 +2871,27 @@ strict_req_fact_pairing_fact_kind(FactId, Kind) :-
2867
2871
  ; Kind = legacy
2868
2872
  ).
2869
2873
 
2874
+ %% strict_req_predicate_grounds_subject(+ReqId, +SubjectKey)
2875
+ % A requirement that constrains a subject fact may ground its claim through
2876
+ % requires_predicate instead of requires_property (kb_model's replacementPlan
2877
+ % swaps one for the other). The predicate pairs with the subject when its
2878
+ % first argument is the subject_key, the argument position built-in and
2879
+ % project-local schemas use for the governed subject.
2880
+ % implements REQ-check-strict-pairing-predicate-grounding
2881
+ strict_req_predicate_grounds_subject(ReqId, SubjectKey) :-
2882
+ kb:effective_req_predicate(ReqId, _FactId, _Namespace, _Name, [First|_], _Polarity),
2883
+ First == SubjectKey,
2884
+ !.
2885
+
2870
2886
  strict_req_fact_pairing_kind_label(legacy, "a legacy fact without fact_kind").
2871
2887
  strict_req_fact_pairing_kind_label(Kind, Label) :-
2872
2888
  format(string(Label), "a fact_kind=~w fact", [Kind]).
2873
2889
 
2874
2890
  %% check_strict_readiness(-Violations)
2875
2891
  % Reports current strict-readiness levels for requirements that are still not
2876
- % contradiction-ready. Legacy and prose-only requirements remain audit-only and
2892
+ % contradiction-ready. Each requirement has exactly one level: the first
2893
+ % strict_readiness_level/2 clause that holds, so the level is computed before
2894
+ % it is compared. Legacy and prose-only requirements remain audit-only and
2877
2895
  % are intentionally not treated as contradictions.
2878
2896
  check_strict_readiness(Violations) :-
2879
2897
  findall(
@@ -2899,7 +2917,8 @@ strict_readiness_issue(
2899
2917
  "Add a subject fact via constrains and a property_value fact via requires_property to model contradiction-safe semantics"
2900
2918
  ) :-
2901
2919
  kb_entity(ReqId, req, _),
2902
- strict_readiness_level(ReqId, prose_only).
2920
+ strict_readiness_level(ReqId, Level),
2921
+ Level == prose_only.
2903
2922
 
2904
2923
  strict_readiness_issue(
2905
2924
  ReqId,
@@ -2907,19 +2926,21 @@ strict_readiness_issue(
2907
2926
  "Replace prose or legacy fact links with a subject fact via constrains and a property_value fact via requires_property"
2908
2927
  ) :-
2909
2928
  kb_entity(ReqId, req, _),
2910
- strict_readiness_level(ReqId, traceable).
2929
+ strict_readiness_level(ReqId, Level),
2930
+ Level == traceable.
2911
2931
 
2912
2932
  strict_readiness_issue(
2913
2933
  ReqId,
2914
2934
  Description,
2915
- "Add a matching property_value fact via requires_property for the same subject_key"
2935
+ "Add a matching property_value fact via requires_property for the same subject_key, or link requires_predicate to a predicate fact whose first argument is that subject_key"
2916
2936
  ) :-
2917
2937
  kb_entity(ReqId, req, _),
2918
- strict_readiness_level(ReqId, has_subject),
2938
+ strict_readiness_level(ReqId, Level),
2939
+ Level == has_subject,
2919
2940
  strict_readiness_primary_subject(ReqId, SubjectFactId, SubjectKey),
2920
2941
  format(
2921
2942
  string(Description),
2922
- "Strict readiness: not-ready (has-subject). Requirement constrains ~w (~w) but has no matching strict requires_property fact, so contradiction checks skip it.",
2943
+ "Strict readiness: not-ready (has-subject). Requirement constrains ~w (~w) but has no matching strict requires_property fact and no requires_predicate fact about that subject, so contradiction checks skip it.",
2923
2944
  [SubjectFactId, SubjectKey]
2924
2945
  ).
2925
2946
 
@@ -2929,7 +2950,8 @@ strict_readiness_issue(
2929
2950
  "Ensure constrains and requires_property use the same subject_key, and keep the requirement current if it should participate in contradiction checks"
2930
2951
  ) :-
2931
2952
  kb_entity(ReqId, req, _),
2932
- strict_readiness_level(ReqId, strict_ready).
2953
+ strict_readiness_level(ReqId, Level),
2954
+ Level == strict_ready.
2933
2955
 
2934
2956
  strict_readiness_level(ReqId, contradiction_ready) :-
2935
2957
  kb:current_req(ReqId),
@@ -2948,6 +2970,11 @@ strict_readiness_level(ReqId, contradiction_ready) :-
2948
2970
  _ValidTo
2949
2971
  ),
2950
2972
  !.
2973
+ strict_readiness_level(ReqId, contradiction_ready) :-
2974
+ kb:current_req(ReqId),
2975
+ strict_readiness_primary_subject(ReqId, _SubjectFactId, SubjectKey),
2976
+ strict_req_predicate_grounds_subject(ReqId, SubjectKey),
2977
+ !.
2951
2978
  strict_readiness_level(ReqId, strict_ready) :-
2952
2979
  strict_readiness_has_strict_subject(ReqId),
2953
2980
  strict_readiness_has_strict_property(ReqId),
@@ -3332,6 +3359,89 @@ inventory_entry_status(Entry, Status) :-
3332
3359
  inventory_entry_status(Entry, Status) :-
3333
3360
  is_list(Entry), memberchk(status=Raw, Entry), normalize_term_atom(Raw, Status).
3334
3361
 
3362
+ %% check_related_requirement_unmodeled(-Violations)
3363
+ % implements REQ-check-related-requirement-unmodeled
3364
+ % domain-contradictions compares grounded facts only. A current requirement
3365
+ % whose proposition ledger still carries `missing` entries contributes no
3366
+ % facts, so when it relates_to a current requirement that is modeled (strict
3367
+ % subject/property facts or ground predicate facts) its claims are never
3368
+ % compared with that requirement: it can describe behavior the modeled one
3369
+ % forbids and `kb_check` stays clean. The relates_to edge says the author knew
3370
+ % the two overlap, so the gap is blocking: model the missing propositions
3371
+ % against the same subject keys or predicates, or supersede the older
3372
+ % requirement. Requirements without a ledger stay in the strict-readiness
3373
+ % migration lane and are not reported here.
3374
+ check_related_requirement_unmodeled(Violations) :-
3375
+ findall(Violation, related_requirement_unmodeled_violation(Violation), Raw),
3376
+ sort(Raw, Violations).
3377
+
3378
+ related_requirement_unmodeled_violation(violation(
3379
+ 'related-requirement-unmodeled',
3380
+ ReqId,
3381
+ Description,
3382
+ Suggestion,
3383
+ Source
3384
+ )) :-
3385
+ kb:current_req(ReqId),
3386
+ requirement_missing_proposition_count(ReqId, MissingCount),
3387
+ MissingCount > 0,
3388
+ related_current_requirement(ReqId, OtherId),
3389
+ modeled_requirement_summary(OtherId, Summary),
3390
+ format(
3391
+ string(Description),
3392
+ "Requirement ~w leaves ~w proposition(s) unmodeled (status missing) while it relates_to ~w, which models ~w; domain-contradictions compares grounded facts only, so these claims are never checked against ~w",
3393
+ [ReqId, MissingCount, OtherId, Summary, OtherId]
3394
+ ),
3395
+ format(
3396
+ string(Suggestion),
3397
+ "Model the missing propositions of ~w against ~w (a subject fact via constrains and property_value facts via requires_property on the same subject_key, or ground predicate facts via requires_predicate), or record that ~w supersedes ~w if it replaces that requirement",
3398
+ [ReqId, Summary, ReqId, OtherId]
3399
+ ),
3400
+ violation_source(ReqId, req, Source).
3401
+
3402
+ requirement_missing_proposition_count(ReqId, Count) :-
3403
+ kb_entity(ReqId, req, Props),
3404
+ memberchk(semantic_inventory=RawInventory, Props),
3405
+ inventory_entries(RawInventory, Entries),
3406
+ aggregate_all(
3407
+ count,
3408
+ ( member(Entry, Entries), inventory_entry_status(Entry, missing) ),
3409
+ Count
3410
+ ).
3411
+
3412
+ related_current_requirement(ReqId, OtherId) :-
3413
+ ( kb_relationship(relates_to, ReqId, OtherId)
3414
+ ; kb_relationship(relates_to, OtherId, ReqId)
3415
+ ),
3416
+ OtherId \== ReqId,
3417
+ kb:current_req(OtherId).
3418
+
3419
+ %% modeled_requirement_summary(+ReqId, -Summary)
3420
+ % Comma-separated list of the subject.property keys the requirement constrains
3421
+ % through contradiction-ready strict facts and the canonical keys of the ground
3422
+ % predicate facts it requires. Fails when the requirement models nothing.
3423
+ modeled_requirement_summary(ReqId, Summary) :-
3424
+ setof(Key, modeled_requirement_key(ReqId, Key), Keys),
3425
+ atomic_list_concat(Keys, ', ', Summary).
3426
+
3427
+ modeled_requirement_key(ReqId, Key) :-
3428
+ kb:effective_req_property_fact(
3429
+ ReqId, SubjectKey, _FactId, PropertyKey,
3430
+ _Operator, _ValueType, _Value, _Unit, _Scope, _Polarity, _ValidFrom, _ValidTo
3431
+ ),
3432
+ normalize_term_atom(SubjectKey, SubjectAtom),
3433
+ normalize_term_atom(PropertyKey, PropertyAtom),
3434
+ format(atom(Key), "~w.~w", [SubjectAtom, PropertyAtom]).
3435
+ modeled_requirement_key(ReqId, Key) :-
3436
+ kb_relationship(requires_predicate, ReqId, FactId),
3437
+ kb_entity(FactId, fact, Props),
3438
+ predicate_verifiability_fact_kind(Props, predicate),
3439
+ ( memberchk(canonical_key=RawKey, Props)
3440
+ -> normalize_term_atom(RawKey, Key)
3441
+ ; memberchk(predicate_name=RawName, Props),
3442
+ normalize_term_atom(RawName, Key)
3443
+ ).
3444
+
3335
3445
  strict_readiness_has_fact_link(ReqId) :-
3336
3446
  kb_relationship(constrains, ReqId, FactId),
3337
3447
  kb_entity(FactId, fact, _),
@@ -3427,6 +3537,7 @@ check_selected_dispatch(Rules, _{
3427
3537
  rule_safety: RuleSafety,
3428
3538
  rule_verifiability: RuleVerifiability,
3429
3539
  semantic_completeness: SemanticCompleteness,
3540
+ related_requirement_unmodeled: RelatedRequirementUnmodeled,
3430
3541
  req_status_vocabulary: ReqStatusVocabulary,
3431
3542
  proof_contract_symbols: ProofContractSymbols,
3432
3543
  entity_id_style: EntityIdStyle,
@@ -3461,6 +3572,7 @@ check_selected_dispatch(Rules, _{
3461
3572
  selected_rule(Rules, 'rule-safety', check_rule_safety, RuleSafety),
3462
3573
  selected_rule(Rules, 'rule-verifiability', check_rule_verifiability, RuleVerifiability),
3463
3574
  selected_rule(Rules, 'semantic-completeness', check_semantic_completeness, SemanticCompleteness),
3575
+ selected_rule(Rules, 'related-requirement-unmodeled', check_related_requirement_unmodeled, RelatedRequirementUnmodeled),
3464
3576
  selected_rule(Rules, 'req-status-vocabulary', check_req_status_vocabulary, ReqStatusVocabulary),
3465
3577
  selected_rule(Rules, 'proof-contract-symbols', check_proof_contract_symbols, ProofContractSymbols),
3466
3578
  selected_rule(Rules, 'entity-id-style', check_entity_id_style, EntityIdStyle),
@@ -40,6 +40,7 @@ known_rule('strict-req-fact-pairing').
40
40
  known_rule('predicate-verifiability').
41
41
  known_rule('strict-readiness').
42
42
  known_rule('semantic-completeness').
43
+ known_rule('related-requirement-unmodeled').
43
44
  known_rule('proof-contract-symbols').
44
45
  known_rule('entity-id-style').
45
46
  known_rule('domain-redundancy').
@@ -84,6 +85,7 @@ rule_enforcement_class('strict-req-fact-pairing', advisory).
84
85
  rule_enforcement_class('predicate-verifiability', advisory).
85
86
  rule_enforcement_class('strict-readiness', migration).
86
87
  rule_enforcement_class('semantic-completeness', migration).
88
+ rule_enforcement_class('related-requirement-unmodeled', canonical).
87
89
  rule_enforcement_class('proof-contract-symbols', advisory).
88
90
  rule_enforcement_class('entity-id-style', advisory).
89
91
  rule_enforcement_class('domain-redundancy', advisory).
@@ -128,6 +130,7 @@ rule_implementation('strict-req-fact-pairing', prolog).
128
130
  rule_implementation('predicate-verifiability', prolog).
129
131
  rule_implementation('strict-readiness', prolog).
130
132
  rule_implementation('semantic-completeness', prolog).
133
+ rule_implementation('related-requirement-unmodeled', prolog).
131
134
  rule_implementation('proof-contract-symbols', prolog).
132
135
  rule_implementation('entity-id-style', prolog).
133
136
  rule_implementation('domain-redundancy', prolog).
@@ -169,6 +172,7 @@ rule_predicate('strict-req-fact-pairing', check_strict_req_fact_pairing).
169
172
  rule_predicate('predicate-verifiability', check_predicate_verifiability).
170
173
  rule_predicate('strict-readiness', check_strict_readiness).
171
174
  rule_predicate('semantic-completeness', check_semantic_completeness).
175
+ rule_predicate('related-requirement-unmodeled', check_related_requirement_unmodeled).
172
176
  rule_predicate('proof-contract-symbols', check_proof_contract_symbols).
173
177
  rule_predicate('entity-id-style', check_entity_id_style).
174
178
  rule_predicate('domain-redundancy', check_domain_redundancy).
@@ -203,6 +207,7 @@ rule_predicate_arity('strict-req-fact-pairing', 1).
203
207
  rule_predicate_arity('predicate-verifiability', 1).
204
208
  rule_predicate_arity('strict-readiness', 1).
205
209
  rule_predicate_arity('semantic-completeness', 1).
210
+ rule_predicate_arity('related-requirement-unmodeled', 1).
206
211
  rule_predicate_arity('proof-contract-symbols', 1).
207
212
  rule_predicate_arity('entity-id-style', 1).
208
213
  rule_predicate_arity('domain-redundancy', 1).
@@ -240,6 +245,7 @@ rule_description('strict-req-fact-pairing', 'Detect requirements with incomplete
240
245
  rule_description('predicate-verifiability', 'Detect requires_predicate links that do not target ground fact_kind: predicate facts').
241
246
  rule_description('strict-readiness', 'Report strict contradiction-readiness levels for requirements that are still prose-only or otherwise not contradiction-ready').
242
247
  rule_description('semantic-completeness', 'Every inventoried assertive proposition is modeled or explicitly classified').
248
+ rule_description('related-requirement-unmodeled', 'A current requirement with unresolved (missing) propositions that relates_to a current requirement modeled with strict property or ground predicate facts; its claims are never compared by domain-contradictions until they are modeled against the same subject or predicates, or it supersedes that requirement').
243
249
  rule_description('proof-contract-symbols', 'Detect unresolved required_proofs.symbol_id values, type-shape required proofs, and proof_bindings.source_file disagreement with the named symbol sourceFile').
244
250
  rule_description('entity-id-style', 'Entity IDs name the governed behavior and match their filename stem; new purely numeric IDs are reported at creation boundaries').
245
251
  rule_description('domain-redundancy', 'Two current requirements must not ground the identical logical term or share a ground fact unless linked by supersedes or restates').