kibi-core 0.17.0 → 0.17.2

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/checks.pl +52 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kibi-core",
3
- "version": "0.17.0",
3
+ "version": "0.17.2",
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
@@ -2766,7 +2766,7 @@ strict_req_fact_pairing_violation(violation(
2766
2766
  strict_req_fact_pairing_issue(
2767
2767
  ReqId,
2768
2768
  Description,
2769
- "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 about that subject_key (its subject argument or its subject_key)"
2770
2770
  ) :-
2771
2771
  kb:current_req(ReqId),
2772
2772
  kb_relationship(constrains, ReqId, SubjectFactId),
@@ -2786,9 +2786,10 @@ strict_req_fact_pairing_issue(
2786
2786
  _ValidFrom,
2787
2787
  _ValidTo
2788
2788
  ),
2789
+ \+ strict_req_predicate_grounds_subject(ReqId, SubjectKey),
2789
2790
  format(
2790
2791
  string(Description),
2791
- "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",
2792
2793
  [SubjectFactId, SubjectKey]
2793
2794
  ).
2794
2795
 
@@ -2870,13 +2871,46 @@ strict_req_fact_pairing_fact_kind(FactId, Kind) :-
2870
2871
  ; Kind = legacy
2871
2872
  ).
2872
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 it is
2878
+ % about that subject_key: its own subject_key names it (kb_model sets it for
2879
+ % schemas whose arguments name no subject), or the argument its schema names
2880
+ % `subject` holds it, wherever that argument sits. A predicate without a
2881
+ % project-local schema and without subject_key keeps the catalog convention
2882
+ % of the subject as its first argument.
2883
+ % implements REQ-check-strict-pairing-predicate-grounding-v2
2884
+ strict_req_predicate_grounds_subject(ReqId, SubjectKey) :-
2885
+ kb:effective_req_predicate(ReqId, FactId, Namespace, Name, Args, _Polarity),
2886
+ predicate_fact_subject_key(FactId, Namespace, Name, Args, PredicateSubject),
2887
+ PredicateSubject == SubjectKey,
2888
+ !.
2889
+
2890
+ %% predicate_fact_subject_key(+FactId, +Namespace, +Name, +Args, -SubjectKey)
2891
+ % The subject a predicate fact is about; at most one answer per fact.
2892
+ predicate_fact_subject_key(FactId, _Namespace, _Name, _Args, SubjectKey) :-
2893
+ kb_entity(FactId, fact, Props),
2894
+ memberchk(subject_key=Raw, Props),
2895
+ !,
2896
+ normalize_term_atom(Raw, SubjectKey).
2897
+ predicate_fact_subject_key(_FactId, Namespace, Name, Args, SubjectKey) :-
2898
+ length(Args, Arity),
2899
+ kb:predicate_schema(_SchemaId, Namespace, Name, Arity, ArgumentNames, _Types),
2900
+ !,
2901
+ nth1(Position, ArgumentNames, subject),
2902
+ nth1(Position, Args, SubjectKey).
2903
+ predicate_fact_subject_key(_FactId, _Namespace, _Name, [SubjectKey|_], SubjectKey).
2904
+
2873
2905
  strict_req_fact_pairing_kind_label(legacy, "a legacy fact without fact_kind").
2874
2906
  strict_req_fact_pairing_kind_label(Kind, Label) :-
2875
2907
  format(string(Label), "a fact_kind=~w fact", [Kind]).
2876
2908
 
2877
2909
  %% check_strict_readiness(-Violations)
2878
2910
  % Reports current strict-readiness levels for requirements that are still not
2879
- % contradiction-ready. Legacy and prose-only requirements remain audit-only and
2911
+ % contradiction-ready. Each requirement has exactly one level: the first
2912
+ % strict_readiness_level/2 clause that holds, so the level is computed before
2913
+ % it is compared. Legacy and prose-only requirements remain audit-only and
2880
2914
  % are intentionally not treated as contradictions.
2881
2915
  check_strict_readiness(Violations) :-
2882
2916
  findall(
@@ -2902,7 +2936,8 @@ strict_readiness_issue(
2902
2936
  "Add a subject fact via constrains and a property_value fact via requires_property to model contradiction-safe semantics"
2903
2937
  ) :-
2904
2938
  kb_entity(ReqId, req, _),
2905
- strict_readiness_level(ReqId, prose_only).
2939
+ strict_readiness_level(ReqId, Level),
2940
+ Level == prose_only.
2906
2941
 
2907
2942
  strict_readiness_issue(
2908
2943
  ReqId,
@@ -2910,19 +2945,21 @@ strict_readiness_issue(
2910
2945
  "Replace prose or legacy fact links with a subject fact via constrains and a property_value fact via requires_property"
2911
2946
  ) :-
2912
2947
  kb_entity(ReqId, req, _),
2913
- strict_readiness_level(ReqId, traceable).
2948
+ strict_readiness_level(ReqId, Level),
2949
+ Level == traceable.
2914
2950
 
2915
2951
  strict_readiness_issue(
2916
2952
  ReqId,
2917
2953
  Description,
2918
- "Add a matching property_value fact via requires_property for the same subject_key"
2954
+ "Add a matching property_value fact via requires_property for the same subject_key, or link requires_predicate to a predicate fact about that subject_key (its subject argument or its subject_key)"
2919
2955
  ) :-
2920
2956
  kb_entity(ReqId, req, _),
2921
- strict_readiness_level(ReqId, has_subject),
2957
+ strict_readiness_level(ReqId, Level),
2958
+ Level == has_subject,
2922
2959
  strict_readiness_primary_subject(ReqId, SubjectFactId, SubjectKey),
2923
2960
  format(
2924
2961
  string(Description),
2925
- "Strict readiness: not-ready (has-subject). Requirement constrains ~w (~w) but has no matching strict requires_property fact, so contradiction checks skip it.",
2962
+ "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.",
2926
2963
  [SubjectFactId, SubjectKey]
2927
2964
  ).
2928
2965
 
@@ -2932,7 +2969,8 @@ strict_readiness_issue(
2932
2969
  "Ensure constrains and requires_property use the same subject_key, and keep the requirement current if it should participate in contradiction checks"
2933
2970
  ) :-
2934
2971
  kb_entity(ReqId, req, _),
2935
- strict_readiness_level(ReqId, strict_ready).
2972
+ strict_readiness_level(ReqId, Level),
2973
+ Level == strict_ready.
2936
2974
 
2937
2975
  strict_readiness_level(ReqId, contradiction_ready) :-
2938
2976
  kb:current_req(ReqId),
@@ -2951,6 +2989,11 @@ strict_readiness_level(ReqId, contradiction_ready) :-
2951
2989
  _ValidTo
2952
2990
  ),
2953
2991
  !.
2992
+ strict_readiness_level(ReqId, contradiction_ready) :-
2993
+ kb:current_req(ReqId),
2994
+ strict_readiness_primary_subject(ReqId, _SubjectFactId, SubjectKey),
2995
+ strict_req_predicate_grounds_subject(ReqId, SubjectKey),
2996
+ !.
2954
2997
  strict_readiness_level(ReqId, strict_ready) :-
2955
2998
  strict_readiness_has_strict_subject(ReqId),
2956
2999
  strict_readiness_has_strict_property(ReqId),