kibi-core 0.11.0 → 0.13.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 +2 -5
- package/schema/entities.pl +10 -4
- package/schema/validation.pl +3 -2
- package/src/checks.pl +199 -5
- package/src/discovery.pl +161 -4
- package/src/kb.pl +68 -5
- package/src/requirement_proof.pl +695 -145
- package/src/rule_registry.pl +137 -0
- package/src/status.pl +38 -19
- package/src/symbol_classification.pl +47 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
% Module: rule_registry
|
|
2
|
+
% GENERATED by scripts/generate-rule-registry.mjs from
|
|
3
|
+
% packages/core/schema/rule-registry.json. Do not edit directly.
|
|
4
|
+
%
|
|
5
|
+
% Registry facts shared by TS and Prolog so unknown rule names fail loudly
|
|
6
|
+
% instead of silently returning empty results.
|
|
7
|
+
|
|
8
|
+
:- module(rule_registry, [
|
|
9
|
+
known_rule/1,
|
|
10
|
+
rule_enforcement_class/2,
|
|
11
|
+
rule_implementation/2,
|
|
12
|
+
rule_predicate/2,
|
|
13
|
+
rule_predicate_arity/2,
|
|
14
|
+
rule_description/2
|
|
15
|
+
]).
|
|
16
|
+
|
|
17
|
+
known_rule('must-priority-coverage').
|
|
18
|
+
known_rule('symbol-coverage').
|
|
19
|
+
known_rule('symbol-traceability').
|
|
20
|
+
known_rule('no-dangling-refs').
|
|
21
|
+
known_rule('source-relationship-parity').
|
|
22
|
+
known_rule('no-cycles').
|
|
23
|
+
known_rule('required-fields').
|
|
24
|
+
known_rule('deprecated-adr-no-successor').
|
|
25
|
+
known_rule('domain-contradictions').
|
|
26
|
+
known_rule('logic-coverage').
|
|
27
|
+
known_rule('rule-safety').
|
|
28
|
+
known_rule('rule-verifiability').
|
|
29
|
+
known_rule('query-plan-safety').
|
|
30
|
+
known_rule('req-status-vocabulary').
|
|
31
|
+
known_rule('strict-fact-shape').
|
|
32
|
+
known_rule('strict-req-fact-pairing').
|
|
33
|
+
known_rule('predicate-verifiability').
|
|
34
|
+
known_rule('strict-readiness').
|
|
35
|
+
known_rule('semantic-completeness').
|
|
36
|
+
known_rule('proof-contract-symbols').
|
|
37
|
+
|
|
38
|
+
rule_enforcement_class('must-priority-coverage', canonical).
|
|
39
|
+
rule_enforcement_class('symbol-coverage', canonical).
|
|
40
|
+
rule_enforcement_class('symbol-traceability', canonical).
|
|
41
|
+
rule_enforcement_class('no-dangling-refs', canonical).
|
|
42
|
+
rule_enforcement_class('source-relationship-parity', canonical).
|
|
43
|
+
rule_enforcement_class('no-cycles', canonical).
|
|
44
|
+
rule_enforcement_class('required-fields', canonical).
|
|
45
|
+
rule_enforcement_class('deprecated-adr-no-successor', canonical).
|
|
46
|
+
rule_enforcement_class('domain-contradictions', canonical).
|
|
47
|
+
rule_enforcement_class('logic-coverage', canonical).
|
|
48
|
+
rule_enforcement_class('rule-safety', canonical).
|
|
49
|
+
rule_enforcement_class('rule-verifiability', canonical).
|
|
50
|
+
rule_enforcement_class('query-plan-safety', canonical).
|
|
51
|
+
rule_enforcement_class('req-status-vocabulary', canonical).
|
|
52
|
+
rule_enforcement_class('strict-fact-shape', advisory).
|
|
53
|
+
rule_enforcement_class('strict-req-fact-pairing', advisory).
|
|
54
|
+
rule_enforcement_class('predicate-verifiability', advisory).
|
|
55
|
+
rule_enforcement_class('strict-readiness', migration).
|
|
56
|
+
rule_enforcement_class('semantic-completeness', migration).
|
|
57
|
+
rule_enforcement_class('proof-contract-symbols', advisory).
|
|
58
|
+
|
|
59
|
+
rule_implementation('must-priority-coverage', prolog).
|
|
60
|
+
rule_implementation('symbol-coverage', prolog).
|
|
61
|
+
rule_implementation('symbol-traceability', prolog).
|
|
62
|
+
rule_implementation('no-dangling-refs', prolog).
|
|
63
|
+
rule_implementation('source-relationship-parity', typescript).
|
|
64
|
+
rule_implementation('no-cycles', prolog).
|
|
65
|
+
rule_implementation('required-fields', prolog).
|
|
66
|
+
rule_implementation('deprecated-adr-no-successor', prolog).
|
|
67
|
+
rule_implementation('domain-contradictions', prolog).
|
|
68
|
+
rule_implementation('logic-coverage', prolog).
|
|
69
|
+
rule_implementation('rule-safety', prolog).
|
|
70
|
+
rule_implementation('rule-verifiability', prolog).
|
|
71
|
+
rule_implementation('query-plan-safety', typescript).
|
|
72
|
+
rule_implementation('req-status-vocabulary', prolog).
|
|
73
|
+
rule_implementation('strict-fact-shape', prolog).
|
|
74
|
+
rule_implementation('strict-req-fact-pairing', prolog).
|
|
75
|
+
rule_implementation('predicate-verifiability', prolog).
|
|
76
|
+
rule_implementation('strict-readiness', prolog).
|
|
77
|
+
rule_implementation('semantic-completeness', prolog).
|
|
78
|
+
rule_implementation('proof-contract-symbols', prolog).
|
|
79
|
+
|
|
80
|
+
rule_predicate('must-priority-coverage', check_must_priority_coverage).
|
|
81
|
+
rule_predicate('symbol-coverage', check_symbol_coverage).
|
|
82
|
+
rule_predicate('symbol-traceability', check_symbol_traceability).
|
|
83
|
+
rule_predicate('no-dangling-refs', check_no_dangling_refs).
|
|
84
|
+
rule_predicate('no-cycles', check_no_cycles).
|
|
85
|
+
rule_predicate('required-fields', check_required_fields).
|
|
86
|
+
rule_predicate('deprecated-adr-no-successor', check_deprecated_adrs).
|
|
87
|
+
rule_predicate('domain-contradictions', check_domain_contradictions).
|
|
88
|
+
rule_predicate('logic-coverage', check_logic_coverage).
|
|
89
|
+
rule_predicate('rule-safety', check_rule_safety).
|
|
90
|
+
rule_predicate('rule-verifiability', check_rule_verifiability).
|
|
91
|
+
rule_predicate('req-status-vocabulary', check_req_status_vocabulary).
|
|
92
|
+
rule_predicate('strict-fact-shape', check_strict_fact_shape).
|
|
93
|
+
rule_predicate('strict-req-fact-pairing', check_strict_req_fact_pairing).
|
|
94
|
+
rule_predicate('predicate-verifiability', check_predicate_verifiability).
|
|
95
|
+
rule_predicate('strict-readiness', check_strict_readiness).
|
|
96
|
+
rule_predicate('semantic-completeness', check_semantic_completeness).
|
|
97
|
+
rule_predicate('proof-contract-symbols', check_proof_contract_symbols).
|
|
98
|
+
|
|
99
|
+
rule_predicate_arity('must-priority-coverage', 1).
|
|
100
|
+
rule_predicate_arity('symbol-coverage', 1).
|
|
101
|
+
rule_predicate_arity('symbol-traceability', 2).
|
|
102
|
+
rule_predicate_arity('no-dangling-refs', 1).
|
|
103
|
+
rule_predicate_arity('no-cycles', 1).
|
|
104
|
+
rule_predicate_arity('required-fields', 1).
|
|
105
|
+
rule_predicate_arity('deprecated-adr-no-successor', 1).
|
|
106
|
+
rule_predicate_arity('domain-contradictions', 1).
|
|
107
|
+
rule_predicate_arity('logic-coverage', 1).
|
|
108
|
+
rule_predicate_arity('rule-safety', 1).
|
|
109
|
+
rule_predicate_arity('rule-verifiability', 1).
|
|
110
|
+
rule_predicate_arity('req-status-vocabulary', 1).
|
|
111
|
+
rule_predicate_arity('strict-fact-shape', 1).
|
|
112
|
+
rule_predicate_arity('strict-req-fact-pairing', 1).
|
|
113
|
+
rule_predicate_arity('predicate-verifiability', 1).
|
|
114
|
+
rule_predicate_arity('strict-readiness', 1).
|
|
115
|
+
rule_predicate_arity('semantic-completeness', 1).
|
|
116
|
+
rule_predicate_arity('proof-contract-symbols', 1).
|
|
117
|
+
|
|
118
|
+
rule_description('must-priority-coverage', 'Every must-priority requirement must have a scenario and a test').
|
|
119
|
+
rule_description('symbol-coverage', 'Production symbols need qualifying coverage via covered_by plus a canonical requirement/scenario test path').
|
|
120
|
+
rule_description('symbol-traceability', 'Production symbols must directly implement requirements for ownership; covered_by is coverage only and executable_for is test identity only').
|
|
121
|
+
rule_description('no-dangling-refs', 'All relationship targets must exist in the KB').
|
|
122
|
+
rule_description('source-relationship-parity', 'Authored Markdown and relationship-shard edges must exactly match the compiled KB').
|
|
123
|
+
rule_description('no-cycles', 'No circular dependency chains in requirements').
|
|
124
|
+
rule_description('required-fields', 'All entities must have required fields').
|
|
125
|
+
rule_description('deprecated-adr-no-successor', 'Deprecated ADRs must have a successor ADR that supersedes them').
|
|
126
|
+
rule_description('domain-contradictions', 'Detect contradictions between requirements constraining the same fact').
|
|
127
|
+
rule_description('logic-coverage', 'Require every explicitly declared atomic requirement claim to be grounded by a linked strict-property or predicate fact').
|
|
128
|
+
rule_description('rule-safety', 'Stored Logic IR rules use only the typed, bounded, stratified vocabulary').
|
|
129
|
+
rule_description('rule-verifiability', 'Requirement rule links resolve to safe rules and registered rule schemas').
|
|
130
|
+
rule_description('query-plan-safety', 'Detect Prolog validation clauses that place negation before generator calls').
|
|
131
|
+
rule_description('req-status-vocabulary', 'Requirement statuses must use the canonical vocabulary (open, in_progress, closed; legacy: active, approved); ADR statuses such as accepted silently fall out of the proof ladder').
|
|
132
|
+
rule_description('strict-fact-shape', 'Detect malformed strict facts (facts with fact_kind that are missing required fields)').
|
|
133
|
+
rule_description('strict-req-fact-pairing', 'Detect requirements with incomplete strict subject/property fact pairing for contradiction-safe semantics').
|
|
134
|
+
rule_description('predicate-verifiability', 'Detect requires_predicate links that do not target ground fact_kind: predicate facts').
|
|
135
|
+
rule_description('strict-readiness', 'Report strict contradiction-readiness levels for requirements that are still prose-only or otherwise not contradiction-ready').
|
|
136
|
+
rule_description('semantic-completeness', 'Every inventoried assertive proposition is modeled or explicitly classified').
|
|
137
|
+
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').
|
package/src/status.pl
CHANGED
|
@@ -112,9 +112,10 @@ freshness_state(DataFile, false, fresh) :-
|
|
|
112
112
|
freshness_state(_, true, unknown).
|
|
113
113
|
|
|
114
114
|
stale_reasons(Reasons, Count, Truncated) :-
|
|
115
|
-
|
|
116
|
-
findall(Reason,
|
|
117
|
-
findall(Reason,
|
|
115
|
+
entity_source_id_index(Index),
|
|
116
|
+
findall(Reason, stale_indexed_source_reason(Index, Reason), IndexedReasons),
|
|
117
|
+
findall(Reason, stale_knowledge_lane_reason(Index, Reason), KnowledgeReasons),
|
|
118
|
+
findall(Reason, stale_documentation_reason(Index, Reason), DocumentationReasons),
|
|
118
119
|
append(IndexedReasons, KnowledgeReasons, IndexedAndKnowledge),
|
|
119
120
|
append(IndexedAndKnowledge, DocumentationReasons, Reasons0),
|
|
120
121
|
sort(Reasons0, Sorted),
|
|
@@ -124,25 +125,25 @@ stale_reasons(Reasons, Count, Truncated) :-
|
|
|
124
125
|
; Reasons = Sorted, Truncated = false
|
|
125
126
|
).
|
|
126
127
|
|
|
127
|
-
stale_indexed_source_reason(Reason) :-
|
|
128
|
+
stale_indexed_source_reason(Index, Reason) :-
|
|
128
129
|
attached_workspace_root(WorkspaceRoot),
|
|
129
130
|
kb:kb_indexed_sources(Sources),
|
|
131
|
+
kb_snapshot_time(SnapshotTime),
|
|
130
132
|
member(SourceAtom, Sources),
|
|
131
133
|
repo_relative_source(SourceAtom, RelativeSource),
|
|
132
134
|
directory_file_path(WorkspaceRoot, RelativeSource, SourcePath),
|
|
133
135
|
( exists_file(SourcePath)
|
|
134
136
|
-> time_file(SourcePath, FileTime),
|
|
135
|
-
kb_snapshot_time(SnapshotTime),
|
|
136
137
|
FileTime > SnapshotTime,
|
|
137
138
|
Code = indexed_source_newer
|
|
138
139
|
; exists_directory(SourcePath)
|
|
139
140
|
-> fail
|
|
140
141
|
; Code = indexed_source_missing
|
|
141
142
|
),
|
|
142
|
-
entity_ids_for_source(RelativeSource, EntityIds),
|
|
143
|
+
entity_ids_for_source(Index, RelativeSource, EntityIds),
|
|
143
144
|
Reason = _{code: Code, path: RelativeSource, entityIds: EntityIds}.
|
|
144
145
|
|
|
145
|
-
stale_knowledge_lane_reason(Reason) :-
|
|
146
|
+
stale_knowledge_lane_reason(Index, Reason) :-
|
|
146
147
|
attached_workspace_root(WorkspaceRoot),
|
|
147
148
|
knowledge_lane(Lane),
|
|
148
149
|
directory_file_path(WorkspaceRoot, '.kb', KbRoot),
|
|
@@ -151,17 +152,17 @@ stale_knowledge_lane_reason(Reason) :-
|
|
|
151
152
|
kb_snapshot_time(SnapshotTime),
|
|
152
153
|
directory_tree_newer_path(LaneRoot, SnapshotTime, Path),
|
|
153
154
|
workspace_relative_path(WorkspaceRoot, Path, RelativePath),
|
|
154
|
-
entity_ids_for_source(RelativePath, EntityIds),
|
|
155
|
+
entity_ids_for_source(Index, RelativePath, EntityIds),
|
|
155
156
|
Reason = _{code: knowledge_source_newer, path: RelativePath, entityIds: EntityIds}.
|
|
156
157
|
|
|
157
|
-
stale_documentation_reason(Reason) :-
|
|
158
|
+
stale_documentation_reason(Index, Reason) :-
|
|
158
159
|
attached_workspace_root(WorkspaceRoot),
|
|
159
160
|
directory_file_path(WorkspaceRoot, 'documentation', DocumentationRoot),
|
|
160
161
|
exists_directory(DocumentationRoot),
|
|
161
162
|
kb_snapshot_time(SnapshotTime),
|
|
162
163
|
directory_tree_newer_path(DocumentationRoot, SnapshotTime, Path),
|
|
163
164
|
workspace_relative_path(WorkspaceRoot, Path, RelativePath),
|
|
164
|
-
entity_ids_for_source(RelativePath, EntityIds),
|
|
165
|
+
entity_ids_for_source(Index, RelativePath, EntityIds),
|
|
165
166
|
Reason = _{code: documentation_source_newer, path: RelativePath, entityIds: EntityIds}.
|
|
166
167
|
|
|
167
168
|
kb_snapshot_time(SnapshotTime) :-
|
|
@@ -173,15 +174,33 @@ kb_snapshot_time(SnapshotTime) :-
|
|
|
173
174
|
; SnapshotTime = 0
|
|
174
175
|
).
|
|
175
176
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
177
|
+
% One pass over all entities builds the repo-relative source -> entity-id
|
|
178
|
+
% lookup used by every stale reason. The previous per-path full enumeration
|
|
179
|
+
% made kb_status_json quadratic (paths x entities) and could wedge large KBs
|
|
180
|
+
% for minutes whenever mtime churn (e.g. a git checkout) marked whole lanes
|
|
181
|
+
% newer than the snapshot.
|
|
182
|
+
entity_source_id_index(Index) :-
|
|
183
|
+
findall(RelativeSource-Id,
|
|
184
|
+
( kb_entity(Id, _Type, Props),
|
|
185
|
+
entity_source_property(Props, RawSource),
|
|
186
|
+
source_value_atom(RawSource, SourceAtom),
|
|
187
|
+
repo_relative_source(SourceAtom, RelativeSource),
|
|
188
|
+
Id \= ''
|
|
189
|
+
),
|
|
190
|
+
Pairs),
|
|
191
|
+
sort(Pairs, Sorted),
|
|
192
|
+
group_pairs_by_key(Sorted, Grouped),
|
|
193
|
+
maplist(sorted_id_values, Grouped, GroupedEntries),
|
|
194
|
+
dict_create(Index, source_index, GroupedEntries).
|
|
195
|
+
|
|
196
|
+
sorted_id_values(RelativeSource-Ids0, RelativeSource-Ids) :-
|
|
197
|
+
sort(Ids0, Ids).
|
|
198
|
+
|
|
199
|
+
entity_ids_for_source(Index, RelativeSource, EntityIds) :-
|
|
200
|
+
( get_dict(RelativeSource, Index, Ids)
|
|
201
|
+
-> EntityIds = Ids
|
|
202
|
+
; EntityIds = []
|
|
203
|
+
).
|
|
185
204
|
|
|
186
205
|
entity_source_property(Props, RawSource) :-
|
|
187
206
|
memberchk(sourceFile=RawSource, Props),
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
% Module: symbol_classification
|
|
2
|
+
% GENERATED by scripts/generate-symbol-classification.mjs from
|
|
3
|
+
% packages/core/schema/symbol-classification.json. Do not edit directly.
|
|
4
|
+
%
|
|
5
|
+
% Vocabulary facts shared by TS and Prolog so symbol classification cannot
|
|
6
|
+
% drift between the extractors, the manifest gate, and validation.
|
|
7
|
+
|
|
8
|
+
:- module(symbol_classification, [
|
|
9
|
+
allowed_granularity_reason/1,
|
|
10
|
+
coarse_granularity_reason/1,
|
|
11
|
+
symbol_role/1,
|
|
12
|
+
inferred_role/2,
|
|
13
|
+
traceability_relationship_type/1
|
|
14
|
+
]).
|
|
15
|
+
|
|
16
|
+
allowed_granularity_reason('config-artifact').
|
|
17
|
+
allowed_granularity_reason('module-level-behavior').
|
|
18
|
+
allowed_granularity_reason('extractor-miss').
|
|
19
|
+
allowed_granularity_reason('legacy-link').
|
|
20
|
+
allowed_granularity_reason('test-suite').
|
|
21
|
+
|
|
22
|
+
coarse_granularity_reason('config-artifact').
|
|
23
|
+
coarse_granularity_reason('module-level-behavior').
|
|
24
|
+
coarse_granularity_reason('extractor-miss').
|
|
25
|
+
coarse_granularity_reason('test-suite').
|
|
26
|
+
|
|
27
|
+
symbol_role('behavioral').
|
|
28
|
+
symbol_role('structural').
|
|
29
|
+
symbol_role('type-shape').
|
|
30
|
+
symbol_role('config').
|
|
31
|
+
symbol_role('module').
|
|
32
|
+
symbol_role('unknown').
|
|
33
|
+
|
|
34
|
+
inferred_role('function', 'behavioral').
|
|
35
|
+
inferred_role('class', 'behavioral').
|
|
36
|
+
inferred_role('method', 'behavioral').
|
|
37
|
+
inferred_role('property', 'behavioral').
|
|
38
|
+
inferred_role('accessor', 'behavioral').
|
|
39
|
+
inferred_role('interface', 'type-shape').
|
|
40
|
+
inferred_role('type', 'type-shape').
|
|
41
|
+
inferred_role('enum', 'type-shape').
|
|
42
|
+
inferred_role('variable', 'unknown').
|
|
43
|
+
inferred_role('unknown', 'unknown').
|
|
44
|
+
|
|
45
|
+
traceability_relationship_type('implements').
|
|
46
|
+
traceability_relationship_type('covered_by').
|
|
47
|
+
traceability_relationship_type('executable_for').
|