kibi-core 0.22.0 → 0.22.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kibi-core",
3
- "version": "0.22.0",
3
+ "version": "0.22.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
@@ -72,7 +72,7 @@
72
72
  check_subject_key_shape/1,
73
73
  check_ontology_quality/1
74
74
  ]).
75
- :- use_module('logic_ir.pl', [logic_rule_safety/2, logic_rule_from_props/2, logic_rule_render/2, logic_rule_conflict/3, logic_rule_conflict_witness/3, logic_rules_stratified/1, logic_rule_missing_keys/4, functional_predicate_declarations/1, logic_rule_property_form/2]).
75
+ :- use_module('logic_ir.pl', [logic_rule_safety/2, logic_rule_from_props/2, logic_rule_render/2, logic_rule_conflict/3, logic_rule_conflict_witness/4, logic_rules_stratified/1, logic_rule_missing_keys/4, functional_predicate_declarations/1, logic_rule_property_form/2]).
76
76
  % GENERATED registry facts; single source is schema/rule-registry.json.
77
77
  :- use_module('rule_registry.pl', [known_rule/1]).
78
78
 
@@ -2433,7 +2433,8 @@ check_domain_contradictions_and_witnesses(Violations, Witnesses) :-
2433
2433
  % disproven remains status=unresolved rather than becoming consistency.
2434
2434
  check_domain_contradiction_witnesses(Witnesses) :-
2435
2435
  findall(Witness, req_conflict_witness(_ReqA, _ReqB, Witness), GroundWitnesses),
2436
- findall(Witness, rule_contradiction_witness(Witness), RuleWitnesses),
2436
+ functional_predicate_declarations(Functional),
2437
+ findall(Witness, rule_contradiction_witness(Functional, Witness), RuleWitnesses),
2437
2438
  append(GroundWitnesses, RuleWitnesses, Witnesses0),
2438
2439
  sort(Witnesses0, Witnesses).
2439
2440
 
@@ -2622,9 +2623,9 @@ opposing_rule_requirement_facts(ReqA, ReqB, FactA, FactB, RuleA, RuleB) :-
2622
2623
  logic_rule_from_props(PropsA, RuleA),
2623
2624
  logic_rule_from_props(PropsB, RuleB).
2624
2625
 
2625
- rule_contradiction_witness(Witness) :-
2626
+ rule_contradiction_witness(Functional, Witness) :-
2626
2627
  opposing_rule_requirement_facts(ReqA, ReqB, FactA, FactB, RuleA, RuleB),
2627
- logic_rule_conflict_witness(RuleA, RuleB, InternalWitness),
2628
+ logic_rule_conflict_witness(RuleA, RuleB, Functional, InternalWitness),
2628
2629
  InternalWitness.status \= disjoint,
2629
2630
  rule_conflict_side(ReqA, FactA, Left),
2630
2631
  rule_conflict_side(ReqB, FactB, Right),
package/src/kb.pl CHANGED
@@ -2466,12 +2466,36 @@ coverage_gap(Req, missing_test) :-
2466
2466
  has_scenario(Req),
2467
2467
  \+ has_test(Req).
2468
2468
 
2469
+ % implements REQ-core-validation-rules
2470
+ % Only a current must-priority requirement owes scenario and test coverage.
2469
2471
  must_requirement(Req) :-
2470
2472
  kb_entity(Req, req, Props),
2471
2473
  memberchk(priority=Priority, Props),
2472
2474
  normalize_term_atom(Priority, PriorityAtom),
2473
2475
  atom_string(PriorityAtom, PriorityStr),
2474
- sub_string(PriorityStr, _, 4, 0, "must").
2476
+ sub_string(PriorityStr, _, 4, 0, "must"),
2477
+ coverage_current_requirement(Req, Props).
2478
+
2479
+ %% coverage_current_requirement(+Req, +Props)
2480
+ % A requirement is still owed coverage unless it is retired: superseded by
2481
+ % another requirement (the target of `supersedes`), carrying a retired status,
2482
+ % or `closed` without the `implemented` tag (a closed requirement is retired
2483
+ % work unless it records that it was implemented, the same rule the
2484
+ % coverage-depth review applies). A requirement without a status keeps the
2485
+ % obligation.
2486
+ coverage_current_requirement(Req, Props) :-
2487
+ \+ kb_relationship(supersedes, _, Req),
2488
+ ( memberchk(status=RawStatus, Props)
2489
+ -> normalize_term_atom(RawStatus, Status)
2490
+ ; Status = missing
2491
+ ),
2492
+ \+ memberchk(Status, [deprecated, superseded, archived, removed, deleted, rejected]),
2493
+ ( Status == closed
2494
+ -> memberchk(tags=RawTags, Props),
2495
+ normalize_term_atom_list(RawTags, Tags),
2496
+ memberchk(implemented, Tags)
2497
+ ; true
2498
+ ).
2475
2499
 
2476
2500
  has_scenario(Req) :-
2477
2501
  once(kb_relationship(specified_by, Req, _)).
package/src/logic_ir.pl CHANGED
@@ -12,6 +12,7 @@
12
12
  logic_rule_conflict/3,
13
13
  logic_rule_conflict/4,
14
14
  logic_rule_conflict_witness/3,
15
+ logic_rule_conflict_witness/4,
15
16
  logic_rule_missing_keys/4,
16
17
  functional_predicate_declarations/1,
17
18
  logic_atom_signature/2,
@@ -1215,7 +1216,15 @@ dependency_path(Current, Target, Edges, Seen) :-
1215
1216
  % Consumers can attach requirement IDs and source spans without ever treating
1216
1217
  % the rendered Prolog preview as executable source.
1217
1218
  logic_rule_conflict_witness(RuleA, RuleB, Witness) :-
1218
- logic_rule_conflict(RuleA, RuleB, Status),
1219
+ functional_predicate_declarations(Functional),
1220
+ logic_rule_conflict_witness(RuleA, RuleB, Functional, Witness).
1221
+
1222
+ %% logic_rule_conflict_witness(+RuleA, +RuleB, +Functional, -Witness)
1223
+ % As logic_rule_conflict_witness/3 with the functional declarations already
1224
+ % read. Reading them scans every predicate_schema fact, so a caller walking
1225
+ % every opposing rule pair reads them once instead of once per pair.
1226
+ logic_rule_conflict_witness(RuleA, RuleB, Functional, Witness) :-
1227
+ logic_rule_conflict(RuleA, RuleB, Functional, Status),
1219
1228
  RuleA = rule(_KindA, ModalityA, HeadA, BodyA, ExceptionsA, ScopeA, FromA, ToA, SchemaA, _VariablesA),
1220
1229
  RuleB = rule(_KindB, ModalityB, HeadB, BodyB, ExceptionsB, ScopeB, FromB, ToB, SchemaB, _VariablesB),
1221
1230
  Witness = witness{
@@ -62,6 +62,7 @@ known_rule('entity-context-missing').
62
62
  known_rule('entity-context-acknowledged').
63
63
  known_rule('decision-firm-unreferenced').
64
64
  known_rule('decision-firm-superseded').
65
+ known_rule('decision-firm-edited').
65
66
  known_rule('supersedes-reason-missing').
66
67
  known_rule('supersedes-reason-acknowledged').
67
68
  known_rule('policy-ownership').
@@ -115,6 +116,7 @@ rule_enforcement_class('entity-context-missing', canonical).
115
116
  rule_enforcement_class('entity-context-acknowledged', advisory).
116
117
  rule_enforcement_class('decision-firm-unreferenced', canonical).
117
118
  rule_enforcement_class('decision-firm-superseded', canonical).
119
+ rule_enforcement_class('decision-firm-edited', canonical).
118
120
  rule_enforcement_class('supersedes-reason-missing', canonical).
119
121
  rule_enforcement_class('supersedes-reason-acknowledged', advisory).
120
122
  rule_enforcement_class('policy-ownership', canonical).
@@ -168,6 +170,7 @@ rule_implementation('entity-context-missing', typescript).
168
170
  rule_implementation('entity-context-acknowledged', typescript).
169
171
  rule_implementation('decision-firm-unreferenced', typescript).
170
172
  rule_implementation('decision-firm-superseded', typescript).
173
+ rule_implementation('decision-firm-edited', typescript).
171
174
  rule_implementation('supersedes-reason-missing', typescript).
172
175
  rule_implementation('supersedes-reason-acknowledged', typescript).
173
176
  rule_implementation('policy-ownership', typescript).
@@ -243,7 +246,7 @@ rule_predicate_arity('symbol-owner-superseded', 1).
243
246
  rule_predicate_arity('adr-unlinked', 1).
244
247
  rule_predicate_arity('adr-proposed', 1).
245
248
 
246
- rule_description('must-priority-coverage', 'Every must-priority requirement must have a scenario and a test').
249
+ rule_description('must-priority-coverage', 'Every current must-priority requirement (not superseded, retired, or closed without the implemented tag) must have a scenario and a test').
247
250
  rule_description('symbol-coverage', 'Production symbols need qualifying coverage via covered_by plus a canonical requirement/scenario test path').
248
251
  rule_description('symbol-traceability', 'Production symbols must directly implement requirements for ownership; covered_by is coverage only and executable_for is test identity only').
249
252
  rule_description('symbol-granularity', 'A symbol with traceability relationships must not link its source file coarsely while narrower behavioral symbols are available, unless it carries an allowed granularity_reason; the staged gate\'s symbol_granularity_violation evaluated KB-wide').
@@ -291,6 +294,7 @@ rule_description('entity-context-missing', 'A current requirement, scenario, tes
291
294
  rule_description('entity-context-acknowledged', 'Informational: how many current entities carry the review:context-missing tag, so the legacy context backlog stays visible; one summary finding per check').
292
295
  rule_description('decision-firm-unreferenced', 'A requirement or ADR marked firmness: firm must name the human words it rests on: origin.ref (or approval_ref on a requirement); Kibi checks that the reference is present, not that it is genuine').
293
296
  rule_description('decision-firm-superseded', 'A requirement or ADR that supersedes a firm decision, retired or not, must itself be firm (and so carry a ref to the human who changed the rule); a default or exploratory replacement cannot overrule a firm decision').
297
+ rule_description('decision-firm-edited', 'A current requirement or ADR that was firm at HEAD must not have its claim (title, stated meaning, the statement its body derives, an ADR\'s body, or its firmness) changed in place unless the edit cites new human words (a changed origin.ref, or approval_ref on a requirement); supersede it with a firm decision instead').
294
298
  rule_description('supersedes-reason-missing', 'A current requirement or ADR that supersedes another must explain why under a \'Why this changed\' heading (at least 12 words of prose naming the evidence and answering the old decision\'s reasoning); supersede edges recorded before schema 9 are acknowledged in the manifest and exempt').
295
299
  rule_description('supersedes-reason-acknowledged', 'Informational: how many current superseding requirements and ADRs have only supersede edges the schema 9 migration acknowledged without a \'Why this changed\' section; one summary finding per check').
296
300
  rule_description('policy-ownership', 'When a plugin activated for kibi.check-policy.v1 declares ownership rules, every production symbol in a rule\'s file set must implement a current requirement grounded (requires_predicate) in one of the rule\'s predicates; projects without an activated check policy are unaffected').