kibi-core 0.21.0 → 0.22.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 +1 -1
- package/schema/entities.pl +6 -0
- package/src/checks.pl +13 -0
- package/src/discovery.pl +7 -5
- package/src/kb.pl +27 -0
- package/src/rule_registry.pl +20 -0
package/package.json
CHANGED
package/schema/entities.pl
CHANGED
|
@@ -51,6 +51,10 @@ entity_property(req, approval_ref, string).
|
|
|
51
51
|
entity_property(req, rationale, string).
|
|
52
52
|
% Claim keys of the exempted requirement an exception waives (all when absent).
|
|
53
53
|
entity_property(req, exempts_claims, list).
|
|
54
|
+
% How firmly a requirement or ADR was decided: firm, default or exploratory.
|
|
55
|
+
% Absent reads as default.
|
|
56
|
+
entity_property(req, firmness, atom).
|
|
57
|
+
entity_property(adr, firmness, atom).
|
|
54
58
|
% Intended outcome of a scenario: success, rejection or error.
|
|
55
59
|
entity_property(scenario, expects, atom).
|
|
56
60
|
|
|
@@ -143,6 +147,8 @@ optional_property(req, approved_by).
|
|
|
143
147
|
optional_property(req, approval_ref).
|
|
144
148
|
optional_property(req, rationale).
|
|
145
149
|
optional_property(req, exempts_claims).
|
|
150
|
+
optional_property(req, firmness).
|
|
151
|
+
optional_property(adr, firmness).
|
|
146
152
|
optional_property(test, verification_scope).
|
|
147
153
|
optional_property(test, verification_perspective).
|
|
148
154
|
optional_property(test, proof_contract).
|
package/src/checks.pl
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
check_selected_json/2, % Returns only selected rule violations as JSON
|
|
10
10
|
check_must_priority_coverage/1, % Returns list of must-priority violations
|
|
11
11
|
check_symbol_coverage/1, % Returns list of uncovered symbols
|
|
12
|
+
check_changed_symbol_coverage/2, % symbol-coverage restricted to a staged change set
|
|
12
13
|
check_symbol_traceability/2, % Returns list of symbols lacking requirement traceability (ReqAdr option)
|
|
13
14
|
check_proof_contract_symbols/1, % Returns unresolved or unexpected required_proofs symbol issues
|
|
14
15
|
check_no_dangling_refs/1, % Returns list of dangling ref violations
|
|
@@ -198,6 +199,18 @@ check_symbol_coverage(Violations) :-
|
|
|
198
199
|
sort(SymbolIds0, SymbolIds),
|
|
199
200
|
maplist(symbol_coverage_violation, SymbolIds, Violations).
|
|
200
201
|
|
|
202
|
+
%% check_changed_symbol_coverage(+ExtraSymbols, -Violations)
|
|
203
|
+
% The symbol-coverage rule for the staged gate: the same violations
|
|
204
|
+
% check_symbol_coverage/1 reports, restricted to the changed symbols
|
|
205
|
+
% (kb:changed_symbol/1 overlay facts plus ExtraSymbols).
|
|
206
|
+
% implements REQ-014
|
|
207
|
+
check_changed_symbol_coverage(ExtraSymbols, Violations) :-
|
|
208
|
+
findall(SymbolId,
|
|
209
|
+
changed_symbol_no_req_coverage(ExtraSymbols, SymbolId),
|
|
210
|
+
SymbolIds0),
|
|
211
|
+
sort(SymbolIds0, SymbolIds),
|
|
212
|
+
maplist(symbol_coverage_violation, SymbolIds, Violations).
|
|
213
|
+
|
|
201
214
|
symbol_coverage_violation(SymbolId, violation(
|
|
202
215
|
'symbol-coverage',
|
|
203
216
|
SymbolId,
|
package/src/discovery.pl
CHANGED
|
@@ -708,14 +708,18 @@ ask_schema_dict(Namespace, Name, SchemaDict, ArgumentNames) :-
|
|
|
708
708
|
ArgumentNames = SchemaDict.argumentNames.
|
|
709
709
|
ask_schema_dict(_Namespace, _Name, null, none).
|
|
710
710
|
|
|
711
|
+
% A built-in row carries the catalog id that kb_model accepts as schemaId;
|
|
712
|
+
% `stored: false` says no entity with that id exists, so it is not a
|
|
713
|
+
% kb_query id.
|
|
711
714
|
ask_builtin_schema_row(Namespace, Name, Arity, KeyPositions, DecisionPosition, Row) :-
|
|
712
|
-
|
|
715
|
+
kb:builtin_predicate_signature(Name, SchemaId, Names),
|
|
713
716
|
findall(Key, (member(P, KeyPositions), nth1(P, Names, Key)), KeyArguments),
|
|
714
717
|
nth1(DecisionPosition, Names, DecisionArgument),
|
|
715
718
|
aggregate_all(count, kb:predicate_fact(_, Namespace, Name, _, _), FactCount),
|
|
716
719
|
Row = _{
|
|
717
|
-
id:
|
|
720
|
+
id: SchemaId,
|
|
718
721
|
builtin: true,
|
|
722
|
+
stored: false,
|
|
719
723
|
namespace: Namespace,
|
|
720
724
|
name: Name,
|
|
721
725
|
arity: Arity,
|
|
@@ -728,9 +732,6 @@ ask_builtin_schema_row(Namespace, Name, Arity, KeyPositions, DecisionPosition, R
|
|
|
728
732
|
factCount: FactCount
|
|
729
733
|
}.
|
|
730
734
|
|
|
731
|
-
% Keep in step with builtin_decision_predicate/5 in kb.pl.
|
|
732
|
-
builtin_argument_names(permission_rule, [actor, action, resource, decision]).
|
|
733
|
-
|
|
734
735
|
ask_schema_row(SchemaId, Namespace, Name, Arity, ArgumentNames, ArgumentTypes, Row) :-
|
|
735
736
|
kb_entity(SchemaId, fact, Props),
|
|
736
737
|
( memberchk(key_arguments=KeysRaw, Props)
|
|
@@ -755,6 +756,7 @@ ask_schema_row(SchemaId, Namespace, Name, Arity, ArgumentNames, ArgumentTypes, R
|
|
|
755
756
|
Row = _{
|
|
756
757
|
id: SchemaId,
|
|
757
758
|
builtin: false,
|
|
759
|
+
stored: true,
|
|
758
760
|
namespace: Namespace,
|
|
759
761
|
name: Name,
|
|
760
762
|
arity: Arity,
|
package/src/kb.pl
CHANGED
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
adr_chain/2,
|
|
62
62
|
deprecated_no_successor/1,
|
|
63
63
|
symbol_no_req_coverage/2,
|
|
64
|
+
changed_symbol_no_req_coverage/2,
|
|
64
65
|
predicate_schema/6,
|
|
65
66
|
predicate_schema_keys/4,
|
|
66
67
|
predicate_fact/5,
|
|
@@ -2845,6 +2846,15 @@ bind_key_arguments([Position|Positions], ArgsA, ArgsB) :-
|
|
|
2845
2846
|
% predicate-catalog-4.ts (permission_rule: actor, action, resource).
|
|
2846
2847
|
builtin_decision_predicate(default, permission_rule, 4, [1, 2, 3], 4).
|
|
2847
2848
|
|
|
2849
|
+
%% builtin_predicate_signature(?Name, ?SchemaId, ?ArgumentNames)
|
|
2850
|
+
% implements REQ-kibi-query-fact-filters
|
|
2851
|
+
% The catalog id and argument names of a built-in decision predicate. The
|
|
2852
|
+
% id is the one kb_model accepts as schemaId; no entity with that id is
|
|
2853
|
+
% stored, so a kb_query by id finds nothing. Keep in step with
|
|
2854
|
+
% builtin_decision_predicate/5 and the catalog entry in
|
|
2855
|
+
% packages/cli/src/operations/modeling/predicate-catalog-4.ts.
|
|
2856
|
+
builtin_predicate_signature(permission_rule, 'FACT-SCHEMA-PERMISSION-RULE', [actor, action, resource, decision]).
|
|
2857
|
+
|
|
2848
2858
|
%% effective_decision(+Decision, +Polarity, -Effect)
|
|
2849
2859
|
effective_decision(allow, assert, allow).
|
|
2850
2860
|
effective_decision(allow, deny, deny).
|
|
@@ -3318,6 +3328,23 @@ changed_symbol_missing_req(Symbol, MinLinks, Count) :-
|
|
|
3318
3328
|
length(UniqueReqs, Count),
|
|
3319
3329
|
Count < MinLinks.
|
|
3320
3330
|
|
|
3331
|
+
%% changed_symbol_no_req_coverage(+ExtraSymbols, -Symbol)
|
|
3332
|
+
% The full-check symbol-coverage rule restricted to a staged change set: the
|
|
3333
|
+
% overlay changed_symbol/1 facts plus ExtraSymbols (symbols whose staged
|
|
3334
|
+
% manifest entry changed). It reuses symbol_no_req_coverage/2, so the staged
|
|
3335
|
+
% gate and `kibi check` judge coverage identically: a direct req->test edge
|
|
3336
|
+
% counts only while the requirement has no scenario.
|
|
3337
|
+
% implements REQ-014
|
|
3338
|
+
changed_symbol_no_req_coverage(ExtraSymbols, Symbol) :-
|
|
3339
|
+
findall(Candidate,
|
|
3340
|
+
( changed_symbol(Candidate)
|
|
3341
|
+
; member(Candidate, ExtraSymbols)
|
|
3342
|
+
),
|
|
3343
|
+
Candidates0),
|
|
3344
|
+
sort(Candidates0, Candidates),
|
|
3345
|
+
member(Symbol, Candidates),
|
|
3346
|
+
symbol_no_req_coverage(Symbol, _).
|
|
3347
|
+
|
|
3321
3348
|
%% changed_symbol_violation(+Symbol, +MinLinks, -Count, -File, -Line, -Col, -Name)
|
|
3322
3349
|
% Full violation record for a changed symbol missing requirements.
|
|
3323
3350
|
changed_symbol_violation(Symbol, MinLinks, Count, File, Line, Col, Name) :-
|
package/src/rule_registry.pl
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
known_rule('must-priority-coverage').
|
|
18
18
|
known_rule('symbol-coverage').
|
|
19
19
|
known_rule('symbol-traceability').
|
|
20
|
+
known_rule('symbol-granularity').
|
|
20
21
|
known_rule('no-dangling-refs').
|
|
21
22
|
known_rule('source-relationship-parity').
|
|
22
23
|
known_rule('branch-store-not-compiled').
|
|
@@ -59,12 +60,17 @@ known_rule('adr-proposed').
|
|
|
59
60
|
known_rule('predicate-schema-conformance').
|
|
60
61
|
known_rule('entity-context-missing').
|
|
61
62
|
known_rule('entity-context-acknowledged').
|
|
63
|
+
known_rule('decision-firm-unreferenced').
|
|
64
|
+
known_rule('decision-firm-superseded').
|
|
65
|
+
known_rule('supersedes-reason-missing').
|
|
66
|
+
known_rule('supersedes-reason-acknowledged').
|
|
62
67
|
known_rule('policy-ownership').
|
|
63
68
|
known_rule('policy-markers').
|
|
64
69
|
|
|
65
70
|
rule_enforcement_class('must-priority-coverage', canonical).
|
|
66
71
|
rule_enforcement_class('symbol-coverage', canonical).
|
|
67
72
|
rule_enforcement_class('symbol-traceability', canonical).
|
|
73
|
+
rule_enforcement_class('symbol-granularity', canonical).
|
|
68
74
|
rule_enforcement_class('no-dangling-refs', canonical).
|
|
69
75
|
rule_enforcement_class('source-relationship-parity', canonical).
|
|
70
76
|
rule_enforcement_class('branch-store-not-compiled', canonical).
|
|
@@ -107,12 +113,17 @@ rule_enforcement_class('adr-proposed', advisory).
|
|
|
107
113
|
rule_enforcement_class('predicate-schema-conformance', advisory).
|
|
108
114
|
rule_enforcement_class('entity-context-missing', canonical).
|
|
109
115
|
rule_enforcement_class('entity-context-acknowledged', advisory).
|
|
116
|
+
rule_enforcement_class('decision-firm-unreferenced', canonical).
|
|
117
|
+
rule_enforcement_class('decision-firm-superseded', canonical).
|
|
118
|
+
rule_enforcement_class('supersedes-reason-missing', canonical).
|
|
119
|
+
rule_enforcement_class('supersedes-reason-acknowledged', advisory).
|
|
110
120
|
rule_enforcement_class('policy-ownership', canonical).
|
|
111
121
|
rule_enforcement_class('policy-markers', canonical).
|
|
112
122
|
|
|
113
123
|
rule_implementation('must-priority-coverage', prolog).
|
|
114
124
|
rule_implementation('symbol-coverage', prolog).
|
|
115
125
|
rule_implementation('symbol-traceability', prolog).
|
|
126
|
+
rule_implementation('symbol-granularity', typescript).
|
|
116
127
|
rule_implementation('no-dangling-refs', prolog).
|
|
117
128
|
rule_implementation('source-relationship-parity', typescript).
|
|
118
129
|
rule_implementation('branch-store-not-compiled', typescript).
|
|
@@ -155,6 +166,10 @@ rule_implementation('adr-proposed', prolog).
|
|
|
155
166
|
rule_implementation('predicate-schema-conformance', typescript).
|
|
156
167
|
rule_implementation('entity-context-missing', typescript).
|
|
157
168
|
rule_implementation('entity-context-acknowledged', typescript).
|
|
169
|
+
rule_implementation('decision-firm-unreferenced', typescript).
|
|
170
|
+
rule_implementation('decision-firm-superseded', typescript).
|
|
171
|
+
rule_implementation('supersedes-reason-missing', typescript).
|
|
172
|
+
rule_implementation('supersedes-reason-acknowledged', typescript).
|
|
158
173
|
rule_implementation('policy-ownership', typescript).
|
|
159
174
|
rule_implementation('policy-markers', typescript).
|
|
160
175
|
|
|
@@ -231,6 +246,7 @@ rule_predicate_arity('adr-proposed', 1).
|
|
|
231
246
|
rule_description('must-priority-coverage', 'Every must-priority requirement must have a scenario and a test').
|
|
232
247
|
rule_description('symbol-coverage', 'Production symbols need qualifying coverage via covered_by plus a canonical requirement/scenario test path').
|
|
233
248
|
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
|
+
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').
|
|
234
250
|
rule_description('no-dangling-refs', 'All relationship targets must exist in the KB').
|
|
235
251
|
rule_description('source-relationship-parity', 'Authored Markdown and relationship-shard edges must exactly match the compiled KB').
|
|
236
252
|
rule_description('branch-store-not-compiled', 'The current branch\'s KB store must be compiled from the authored .kb/ sources; a missing or empty store is reported once, naming kibi sync, instead of every store-backed rule reading an empty KB').
|
|
@@ -273,5 +289,9 @@ rule_description('adr-proposed', 'Informational: an ADR that is still proposed a
|
|
|
273
289
|
rule_description('predicate-schema-conformance', 'Predicate facts match a predicate_schema (project-local, or the built-in catalog in the default namespace) and use its declared argument constants').
|
|
274
290
|
rule_description('entity-context-missing', 'A current requirement, scenario, test, ADR or observation/meta fact must carry body context: at least 12 words of prose (requirements: under a Context, Rationale, Why, Background, Source, Notes or Evidence heading) that do not restate the title or semantic_text; entities tagged review:context-missing are acknowledged legacy and exempt').
|
|
275
291
|
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
|
+
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
|
+
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').
|
|
294
|
+
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
|
+
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').
|
|
276
296
|
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').
|
|
277
297
|
rule_description('policy-markers', 'When a plugin activated for kibi.check-policy.v1 declares marker rules, every file implementing a requirement grounded in the rule\'s pattern predicate (with its declared sibling files) must contain each marker the KB declares for that pattern').
|