kibi-cli 2.1.0 → 2.2.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.
Files changed (246) hide show
  1. package/dist/cli-protocol.d.ts.map +1 -1
  2. package/dist/cli-protocol.js +3 -2
  3. package/dist/commands/aggregated-checks.d.ts +7 -0
  4. package/dist/commands/aggregated-checks.d.ts.map +1 -1
  5. package/dist/commands/aggregated-checks.js +25 -1
  6. package/dist/commands/check.d.ts.map +1 -1
  7. package/dist/commands/check.js +21 -13
  8. package/dist/commands/doctor.d.ts.map +1 -1
  9. package/dist/commands/doctor.js +105 -24
  10. package/dist/commands/github-init.d.ts +1 -1
  11. package/dist/commands/github-init.d.ts.map +1 -1
  12. package/dist/commands/github-init.js +1 -1
  13. package/dist/commands/init-helpers.d.ts +17 -2
  14. package/dist/commands/init-helpers.d.ts.map +1 -1
  15. package/dist/commands/init-helpers.js +123 -23
  16. package/dist/commands/init.d.ts.map +1 -1
  17. package/dist/commands/init.js +110 -15
  18. package/dist/commands/prove.d.ts.map +1 -1
  19. package/dist/commands/prove.js +10 -18
  20. package/dist/commands/sync/cache.d.ts +20 -1
  21. package/dist/commands/sync/cache.d.ts.map +1 -1
  22. package/dist/commands/sync/cache.js +51 -2
  23. package/dist/commands/sync/discovery.d.ts.map +1 -1
  24. package/dist/commands/sync/discovery.js +1 -1
  25. package/dist/commands/sync/persistence.d.ts.map +1 -1
  26. package/dist/commands/sync/persistence.js +8 -0
  27. package/dist/commands/sync.d.ts.map +1 -1
  28. package/dist/commands/sync.js +11 -3
  29. package/dist/engine.d.ts +26 -0
  30. package/dist/engine.d.ts.map +1 -1
  31. package/dist/engine.js +126 -29
  32. package/dist/extractors/manifest.d.ts.map +1 -1
  33. package/dist/extractors/manifest.js +66 -28
  34. package/dist/extractors/markdown.d.ts +2 -0
  35. package/dist/extractors/markdown.d.ts.map +1 -1
  36. package/dist/extractors/markdown.js +14 -3
  37. package/dist/extractors/relationships.d.ts.map +1 -1
  38. package/dist/extractors/relationships.js +1 -0
  39. package/dist/intent-search.d.ts.map +1 -1
  40. package/dist/intent-search.js +68 -29
  41. package/dist/operations/bootstrap/generate.d.ts.map +1 -1
  42. package/dist/operations/bootstrap/generate.js +4 -3
  43. package/dist/operations/modeling/model-requirement.d.ts +1 -1
  44. package/dist/operations/modeling/model-requirement.d.ts.map +1 -1
  45. package/dist/operations/modeling/model-requirement.js +176 -10
  46. package/dist/operations/modeling/predicate-applyplan.d.ts.map +1 -1
  47. package/dist/operations/modeling/predicate-applyplan.js +14 -2
  48. package/dist/operations/modeling/predicate-loader.d.ts.map +1 -1
  49. package/dist/operations/modeling/predicate-loader.js +24 -0
  50. package/dist/operations/modeling/predicate-types.d.ts +4 -0
  51. package/dist/operations/modeling/predicate-types.d.ts.map +1 -1
  52. package/dist/operations/modeling/predicate-vocabulary.d.ts +54 -0
  53. package/dist/operations/modeling/predicate-vocabulary.d.ts.map +1 -0
  54. package/dist/operations/modeling/predicate-vocabulary.js +169 -0
  55. package/dist/operations/modeling/requirement-types.d.ts +5 -0
  56. package/dist/operations/modeling/requirement-types.d.ts.map +1 -1
  57. package/dist/operations/modeling/vocabulary-alignment.d.ts +60 -0
  58. package/dist/operations/modeling/vocabulary-alignment.d.ts.map +1 -0
  59. package/dist/operations/modeling/vocabulary-alignment.js +178 -0
  60. package/dist/operations/mutation/contradictions.d.ts +3 -0
  61. package/dist/operations/mutation/contradictions.d.ts.map +1 -1
  62. package/dist/operations/mutation/contradictions.js +29 -0
  63. package/dist/operations/mutation/delete.d.ts.map +1 -1
  64. package/dist/operations/mutation/delete.js +33 -1
  65. package/dist/operations/mutation/predicate-vocabulary-guard.d.ts +8 -0
  66. package/dist/operations/mutation/predicate-vocabulary-guard.d.ts.map +1 -0
  67. package/dist/operations/mutation/predicate-vocabulary-guard.js +64 -0
  68. package/dist/operations/mutation/relationships.d.ts +1 -1
  69. package/dist/operations/mutation/relationships.d.ts.map +1 -1
  70. package/dist/operations/mutation/relationships.js +1 -0
  71. package/dist/operations/mutation/saga.d.ts +5 -0
  72. package/dist/operations/mutation/saga.d.ts.map +1 -1
  73. package/dist/operations/mutation/saga.js +10 -0
  74. package/dist/operations/mutation/serialization.d.ts.map +1 -1
  75. package/dist/operations/mutation/serialization.js +2 -0
  76. package/dist/operations/mutation/source-authoring.d.ts +6 -0
  77. package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
  78. package/dist/operations/mutation/source-authoring.js +65 -26
  79. package/dist/operations/mutation/strict-fact.d.ts.map +1 -1
  80. package/dist/operations/mutation/strict-fact.js +5 -0
  81. package/dist/operations/mutation/types.d.ts +17 -0
  82. package/dist/operations/mutation/types.d.ts.map +1 -1
  83. package/dist/operations/mutation/upsert.d.ts +6 -0
  84. package/dist/operations/mutation/upsert.d.ts.map +1 -1
  85. package/dist/operations/mutation/upsert.js +72 -4
  86. package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
  87. package/dist/operations/mutation/validate-upsert.js +24 -1
  88. package/dist/operations/mutation/validation.d.ts.map +1 -1
  89. package/dist/operations/mutation/validation.js +16 -3
  90. package/dist/operations/planning/apply-plan.d.ts.map +1 -1
  91. package/dist/operations/planning/apply-plan.js +61 -17
  92. package/dist/operations/planning/compile-intent.d.ts.map +1 -1
  93. package/dist/operations/planning/compile-intent.js +3 -1
  94. package/dist/operations/proof/code-scope.d.ts +17 -0
  95. package/dist/operations/proof/code-scope.d.ts.map +1 -0
  96. package/dist/operations/proof/code-scope.js +60 -0
  97. package/dist/operations/proof/ingest-proof.d.ts +4 -2
  98. package/dist/operations/proof/ingest-proof.d.ts.map +1 -1
  99. package/dist/operations/proof/ingest-proof.js +207 -74
  100. package/dist/operations/proof/migrate-legacy-receipts.d.ts.map +1 -1
  101. package/dist/operations/proof/migrate-legacy-receipts.js +7 -5
  102. package/dist/operations/proof/prune-receipts.d.ts.map +1 -1
  103. package/dist/operations/proof/prune-receipts.js +7 -5
  104. package/dist/plugins/compose-semantic-classifier.d.ts +6 -1
  105. package/dist/plugins/compose-semantic-classifier.d.ts.map +1 -1
  106. package/dist/plugins/compose-semantic-classifier.js +8 -3
  107. package/dist/plugins/compose-vocabulary-alignment.d.ts +23 -0
  108. package/dist/plugins/compose-vocabulary-alignment.d.ts.map +1 -0
  109. package/dist/plugins/compose-vocabulary-alignment.js +141 -0
  110. package/dist/plugins/external-allowlist.d.ts +7 -0
  111. package/dist/plugins/external-allowlist.d.ts.map +1 -1
  112. package/dist/plugins/external-allowlist.js +13 -0
  113. package/dist/plugins/index.d.ts +2 -0
  114. package/dist/plugins/index.d.ts.map +1 -1
  115. package/dist/plugins/index.js +4 -0
  116. package/dist/plugins/registry.d.ts +2 -1
  117. package/dist/plugins/registry.d.ts.map +1 -1
  118. package/dist/plugins/registry.js +22 -1
  119. package/dist/prolog/codec.d.ts.map +1 -1
  120. package/dist/prolog/codec.js +2 -0
  121. package/dist/prolog.d.ts +36 -0
  122. package/dist/prolog.d.ts.map +1 -1
  123. package/dist/prolog.js +78 -9
  124. package/dist/public/diagnostic-usage.d.ts.map +1 -1
  125. package/dist/public/diagnostic-usage.js +7 -25
  126. package/dist/public/impact/full-kb-quality.d.ts.map +1 -1
  127. package/dist/public/impact/full-kb-quality.js +4 -12
  128. package/dist/public/operations/catalog.d.ts +36 -7
  129. package/dist/public/operations/catalog.d.ts.map +1 -1
  130. package/dist/public/operations/check-executor.d.ts.map +1 -1
  131. package/dist/public/operations/check-executor.js +10 -2
  132. package/dist/public/operations/check-helpers.d.ts +6 -0
  133. package/dist/public/operations/check-helpers.d.ts.map +1 -1
  134. package/dist/public/operations/check-helpers.js +21 -1
  135. package/dist/public/operations/contracts.d.ts.map +1 -1
  136. package/dist/public/operations/contracts.js +16 -0
  137. package/dist/public/operations/discovery-entities.d.ts +42 -2
  138. package/dist/public/operations/discovery-entities.d.ts.map +1 -1
  139. package/dist/public/operations/discovery-entities.js +195 -22
  140. package/dist/public/operations/discovery-executors.d.ts +1 -0
  141. package/dist/public/operations/discovery-executors.d.ts.map +1 -1
  142. package/dist/public/operations/discovery-executors.js +75 -46
  143. package/dist/public/operations/migration-plan.d.ts +2 -0
  144. package/dist/public/operations/migration-plan.d.ts.map +1 -1
  145. package/dist/public/operations/migration-plan.js +50 -0
  146. package/dist/public/operations/predicate-schema-conformance.d.ts +41 -0
  147. package/dist/public/operations/predicate-schema-conformance.d.ts.map +1 -0
  148. package/dist/public/operations/predicate-schema-conformance.js +242 -0
  149. package/dist/public/operations/prolog-json.d.ts.map +1 -1
  150. package/dist/public/operations/prolog-json.js +9 -3
  151. package/dist/public/operations/result-envelope.d.ts +34 -1
  152. package/dist/public/operations/result-envelope.d.ts.map +1 -1
  153. package/dist/public/operations/result-envelope.js +78 -2
  154. package/dist/public/operations/runtime-types.d.ts +1 -1
  155. package/dist/public/operations/runtime-types.d.ts.map +1 -1
  156. package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
  157. package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
  158. package/dist/public/operations/specs/check-rules.generated.js +8 -1
  159. package/dist/public/operations/specs/check.d.ts +1 -1
  160. package/dist/public/operations/specs/discovery.d.ts +7 -1
  161. package/dist/public/operations/specs/discovery.d.ts.map +1 -1
  162. package/dist/public/operations/specs/discovery.js +7 -1
  163. package/dist/public/operations/specs/mutation-schemas.d.ts +27 -4
  164. package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
  165. package/dist/public/operations/specs/mutation-schemas.js +21 -3
  166. package/dist/public/operations/specs/reporting.d.ts +8 -0
  167. package/dist/public/operations/specs/reporting.d.ts.map +1 -1
  168. package/dist/public/operations/specs/reporting.js +46 -15
  169. package/dist/public/operations/specs/upsert.d.ts +28 -5
  170. package/dist/public/operations/specs/upsert.d.ts.map +1 -1
  171. package/dist/public/operations/specs/upsert.js +1 -1
  172. package/dist/public/operations/symbol-repair-plan.d.ts.map +1 -1
  173. package/dist/public/operations/symbol-repair-plan.js +8 -3
  174. package/dist/public/schemas/entity.d.ts.map +1 -1
  175. package/dist/public/schemas/entity.js +22 -0
  176. package/dist/public/schemas/relationship.d.ts.map +1 -1
  177. package/dist/public/schemas/relationship.js +1 -0
  178. package/dist/public/skills/kibi-usage/SKILL.md +7 -3
  179. package/dist/public/skills/kibi-usage/resources/fact-lanes.md +4 -0
  180. package/dist/public/skills/kibi-usage/resources/relationship-directions.md +35 -17
  181. package/dist/public/skills/kibi-usage/resources/source-authoring.md +36 -0
  182. package/dist/public/skills/kibi-usage/resources/workflows.md +52 -1
  183. package/dist/public/telemetry-acceptance.d.ts.map +1 -1
  184. package/dist/public/telemetry-acceptance.js +21 -5
  185. package/dist/relationships/shards.d.ts +6 -0
  186. package/dist/relationships/shards.d.ts.map +1 -1
  187. package/dist/relationships/shards.js +26 -19
  188. package/dist/schemas/entity.schema.json +32 -0
  189. package/dist/traceability/staged-diagnostics.d.ts +1 -1
  190. package/dist/traceability/staged-diagnostics.d.ts.map +1 -1
  191. package/dist/traceability/staged-entity-id-style.d.ts +12 -0
  192. package/dist/traceability/staged-entity-id-style.d.ts.map +1 -0
  193. package/dist/traceability/staged-entity-id-style.js +68 -0
  194. package/dist/traceability/temp-kb.d.ts.map +1 -1
  195. package/dist/traceability/temp-kb.js +8 -0
  196. package/dist/traceability/validate.js +1 -1
  197. package/dist/types/entities.d.ts +2 -0
  198. package/dist/types/entities.d.ts.map +1 -1
  199. package/dist/types/relationships.d.ts +1 -1
  200. package/dist/types/relationships.d.ts.map +1 -1
  201. package/dist/utils/entity-id-style.d.ts +27 -0
  202. package/dist/utils/entity-id-style.d.ts.map +1 -0
  203. package/dist/utils/entity-id-style.js +81 -0
  204. package/dist/utils/git-repository-context.d.ts +50 -0
  205. package/dist/utils/git-repository-context.d.ts.map +1 -0
  206. package/dist/utils/git-repository-context.js +259 -0
  207. package/dist/utils/rule-registry.d.ts +5 -0
  208. package/dist/utils/rule-registry.d.ts.map +1 -1
  209. package/dist/utils/rule-registry.generated.d.ts +37 -0
  210. package/dist/utils/rule-registry.generated.d.ts.map +1 -1
  211. package/dist/utils/rule-registry.generated.js +44 -0
  212. package/dist/utils/strict-modeling.d.ts +7 -0
  213. package/dist/utils/strict-modeling.d.ts.map +1 -1
  214. package/dist/utils/strict-modeling.js +11 -0
  215. package/package.json +4 -4
  216. package/schema/entities.pl +60 -1
  217. package/schema/relationships.pl +17 -4
  218. package/schema/validation.pl +118 -20
  219. package/src/public/diagnostic-usage.ts +16 -24
  220. package/src/public/impact/full-kb-quality.ts +4 -16
  221. package/src/public/operations/check-executor.ts +12 -1
  222. package/src/public/operations/check-helpers.ts +27 -1
  223. package/src/public/operations/contracts.ts +19 -0
  224. package/src/public/operations/discovery-entities.ts +292 -23
  225. package/src/public/operations/discovery-executors.ts +91 -55
  226. package/src/public/operations/migration-plan.ts +57 -0
  227. package/src/public/operations/predicate-schema-conformance.ts +362 -0
  228. package/src/public/operations/prolog-json.ts +9 -3
  229. package/src/public/operations/result-envelope.ts +114 -2
  230. package/src/public/operations/runtime-types.ts +1 -1
  231. package/src/public/operations/specs/check-rules.generated.ts +8 -1
  232. package/src/public/operations/specs/discovery.ts +8 -1
  233. package/src/public/operations/specs/mutation-schemas.ts +23 -3
  234. package/src/public/operations/specs/reporting.ts +69 -22
  235. package/src/public/operations/specs/upsert.ts +1 -1
  236. package/src/public/operations/symbol-repair-plan.ts +13 -3
  237. package/src/public/schemas/entity.ts +22 -0
  238. package/src/public/schemas/relationship.ts +1 -0
  239. package/src/public/skills/kibi-usage/SKILL.md +7 -3
  240. package/src/public/skills/kibi-usage/resources/fact-lanes.md +4 -0
  241. package/src/public/skills/kibi-usage/resources/relationship-directions.md +35 -17
  242. package/src/public/skills/kibi-usage/resources/source-authoring.md +36 -0
  243. package/src/public/skills/kibi-usage/resources/workflows.md +52 -1
  244. package/src/public/telemetry-acceptance.ts +37 -6
  245. package/src/schemas/entity.schema.json +32 -0
  246. package/src/schemas/relationship.schema.json +1 -0
@@ -42,8 +42,10 @@ validate_property_type(Type, Prop, Value) :-
42
42
  % check_kind(Kind, Value) succeeds if Value matches Kind
43
43
  check_kind(atom, V) :- atom(V).
44
44
  check_kind(string, V) :- string(V).
45
+ check_kind(atom_or_string, V) :- atom(V) ; string(V).
45
46
  check_kind(datetime, V) :- string(V). % accept ISO strings for now
46
47
  check_kind(list, V) :- is_list(V).
48
+ check_kind(list_or_json, V) :- is_list(V) ; string(V) ; atom(V).
47
49
  check_kind(uri, V) :- string(V).
48
50
  check_kind(integer, V) :- integer(V).
49
51
  check_kind(number, V) :- number(V).
@@ -59,11 +61,24 @@ validate_entity_shape(fact, Props) :-
59
61
  !,
60
62
  valid_optional_fact_enums(Props),
61
63
  valid_polarity_in_props(Props),
64
+ valid_claim_provenance(Props),
62
65
  ( memberchk(fact_kind=RawKind, Props) -> validate_fact_shape(RawKind, Props) ; true ).
66
+ validate_entity_shape(test, Props) :-
67
+ !,
68
+ valid_optional_test_enums(Props),
69
+ forall(member(Key=_, Props), \+ is_fact_only_field(Key)).
70
+ validate_entity_shape(req, Props) :-
71
+ !,
72
+ forall(member(Key=_, Props), \+ is_fact_only_field(Key)),
73
+ forall(member(Key=_, Props), \+ is_test_only_field(Key)).
63
74
  validate_entity_shape(Type, Props) :-
64
75
  Type \= fact,
65
- % Non-fact entities cannot have fact-only fields
66
- forall(member(Key=_Val, Props), \+ is_fact_only_field(Key)).
76
+ Type \= test,
77
+ Type \= req,
78
+ % Non-fact/non-test entities cannot have type-specific fields
79
+ forall(member(Key=_, Props), \+ is_fact_only_field(Key)),
80
+ forall(member(Key=_, Props), \+ is_test_only_field(Key)),
81
+ forall(member(Key=_, Props), Key \= logic_claims).
67
82
 
68
83
  % is_fact_only_field(+Key) - true if Key is a fact-specific field
69
84
  is_fact_only_field(fact_kind).
@@ -82,12 +97,39 @@ is_fact_only_field(closed_world).
82
97
  is_fact_only_field(valid_from).
83
98
  is_fact_only_field(valid_to).
84
99
  is_fact_only_field(canonical_key).
100
+ is_fact_only_field(claim_key).
101
+ is_fact_only_field(claim_text).
102
+ is_fact_only_field(predicate_name).
103
+ is_fact_only_field(predicate_namespace).
104
+ is_fact_only_field(predicate_arity).
105
+ is_fact_only_field(argument_names).
106
+ is_fact_only_field(argument_types).
107
+ is_fact_only_field(argument_descriptions).
108
+ is_fact_only_field(argument_constants).
109
+ is_fact_only_field(argument_aliases).
110
+ is_fact_only_field(aliases).
111
+ is_fact_only_field(examples).
112
+ is_fact_only_field(predicate_args).
113
+ is_fact_only_field(rule_ir).
114
+ is_fact_only_field(rule_hash).
115
+ is_fact_only_field(rule_schema_id).
116
+ is_fact_only_field(rule_name).
117
+ is_fact_only_field(semantic_key).
118
+ is_fact_only_field(claim_span_start).
119
+ is_fact_only_field(claim_span_end).
120
+
121
+ % is_test_only_field(+Key) - true if Key is a test-specific field
122
+ is_test_only_field(verification_scope).
123
+ is_test_only_field(verification_perspective).
124
+ is_test_only_field(proof_contract).
125
+ is_test_only_field(proof_bindings).
126
+ is_test_only_field(proof_receipts).
85
127
 
86
128
  % validate_fact_shape(+Kind, +Props)
87
129
  validate_fact_shape(subject, Props) :-
88
130
  memberchk(subject_key=_Val, Props),
89
131
  valid_optional_fact_enums(Props),
90
- valid_polarity_in_props(Props).
132
+ valid_strict_polarity_in_props(Props), !.
91
133
  validate_fact_shape(property_value, Props) :-
92
134
  memberchk(subject_key=_Subject, Props),
93
135
  memberchk(property_key=_Property, Props),
@@ -98,48 +140,104 @@ validate_fact_shape(property_value, Props) :-
98
140
  exactly_one_value_field(Props),
99
141
  value_type_matches_field(VT, Props),
100
142
  valid_optional_fact_enums(Props),
101
- valid_polarity_in_props(Props).
143
+ valid_strict_polarity_in_props(Props), !.
102
144
  validate_fact_shape(observation, Props) :-
103
- % Observation facts are allowed but don't require full strict property tuple yet
104
145
  valid_optional_fact_enums(Props),
105
- valid_polarity_in_props(Props).
146
+ valid_polarity_in_props(Props), !.
106
147
  validate_fact_shape(meta, Props) :-
107
148
  % Meta facts are allowed but don't require full strict property tuple yet
108
149
  valid_optional_fact_enums(Props),
109
- valid_polarity_in_props(Props).
150
+ valid_polarity_in_props(Props), !.
151
+ validate_fact_shape(predicate_schema, Props) :-
152
+ memberchk(predicate_name=_Name, Props),
153
+ memberchk(predicate_arity=Arity, Props),
154
+ Arity >= 1,
155
+ memberchk(argument_names=ArgumentNames, Props),
156
+ memberchk(argument_types=ArgumentTypes, Props),
157
+ same_length(ArgumentNames, ArgumentTypes),
158
+ length(ArgumentNames, Arity),
159
+ valid_optional_fact_enums(Props),
160
+ valid_polarity_in_props(Props), !.
161
+ validate_fact_shape(predicate, Props) :-
162
+ memberchk(predicate_name=_Name, Props),
163
+ memberchk(predicate_args=Args, Props),
164
+ Args \= [],
165
+ memberchk(canonical_key=_CanonicalKey, Props),
166
+ valid_optional_fact_enums(Props),
167
+ valid_predicate_polarity_in_props(Props), !.
168
+ validate_fact_shape(rule_schema, Props) :-
169
+ memberchk(rule_name=_Name, Props),
170
+ memberchk(argument_names=ArgumentNames, Props),
171
+ memberchk(argument_types=ArgumentTypes, Props),
172
+ same_length(ArgumentNames, ArgumentTypes),
173
+ valid_optional_fact_enums(Props),
174
+ valid_polarity_in_props(Props), !.
175
+ validate_fact_shape(rule, Props) :-
176
+ memberchk(rule_ir=RuleIr, Props),
177
+ nonempty_claim_value(RuleIr),
178
+ memberchk(rule_hash=_Hash, Props),
179
+ memberchk(rule_schema_id=_SchemaId, Props),
180
+ memberchk(semantic_key=_SemanticKey, Props),
181
+ valid_optional_fact_enums(Props),
182
+ valid_polarity_in_props(Props), !.
110
183
  validate_fact_shape(Kind, _Props) :-
111
184
  % Unknown fact_kind values fail validation
112
- \+ memberchk(Kind, [subject, property_value, observation, meta]),
185
+ \+ memberchk(Kind, [subject, property_value, observation, meta, predicate_schema, predicate, rule_schema, rule]),
113
186
  fail.
114
187
 
115
188
  % valid_operator(+Op)
116
- valid_operator(eq).
117
- valid_operator(neq).
118
- valid_operator(lt).
119
- valid_operator(lte).
120
- valid_operator(gt).
121
- valid_operator(gte).
189
+ valid_operator(Op) :- memberchk(Op, [eq, neq, lt, lte, gt, gte]), !.
122
190
 
123
191
  % valid_value_type(+VT)
124
- valid_value_type(string).
125
- valid_value_type(int).
126
- valid_value_type(number).
127
- valid_value_type(bool).
192
+ valid_value_type(ValueType) :- memberchk(ValueType, [string, int, number, bool]), !.
128
193
 
129
194
  % valid_polarity_in_props(+Props)
130
195
  % Validates polarity if present; succeeds if no polarity in props
131
196
  valid_polarity_in_props(Props) :-
132
197
  ( memberchk(polarity=P, Props) -> valid_polarity(P) ; true ).
133
198
 
199
+ valid_strict_polarity_in_props(Props) :-
200
+ ( memberchk(polarity=P, Props) -> valid_strict_polarity(P) ; true ).
201
+
202
+ valid_predicate_polarity_in_props(Props) :-
203
+ ( memberchk(polarity=P, Props) -> valid_predicate_polarity(P) ; true ).
204
+
205
+ % claim_key and claim_text form one auditable provenance pair.
206
+ valid_claim_provenance(Props) :-
207
+ ( memberchk(claim_key=Key, Props)
208
+ -> memberchk(claim_text=Text, Props),
209
+ nonempty_claim_value(Key),
210
+ nonempty_claim_value(Text)
211
+ ; \+ memberchk(claim_text=_, Props)
212
+ ).
213
+
214
+ nonempty_claim_value(Value) :- string(Value), Value \= "", !.
215
+ nonempty_claim_value(Value) :- atom(Value), Value \= '', !.
216
+
134
217
  % valid_optional_fact_enums(+Props)
135
218
  % Validates enum-typed fact fields whenever they are present
136
219
  valid_optional_fact_enums(Props) :-
137
220
  ( memberchk(operator=Op, Props) -> valid_operator(Op) ; true ),
138
221
  ( memberchk(value_type=VT, Props) -> valid_value_type(VT) ; true ).
139
222
 
223
+ % valid_optional_test_enums(+Props)
224
+ % Validates enum-typed test fields whenever they are present
225
+ valid_optional_test_enums(Props) :-
226
+ ( memberchk(verification_scope=Scope, Props) -> valid_verification_scope(Scope) ; true ),
227
+ ( memberchk(verification_perspective=Perspective, Props) -> valid_verification_perspective(Perspective) ; true ).
228
+
140
229
  % valid_polarity(+P)
141
- valid_polarity(require).
142
- valid_polarity(forbid).
230
+ valid_polarity(Polarity) :- memberchk(Polarity, [require, forbid, assert, deny]), !.
231
+
232
+ valid_strict_polarity(Polarity) :- memberchk(Polarity, [require, forbid]), !.
233
+
234
+ valid_predicate_polarity(Polarity) :- memberchk(Polarity, [assert, deny]), !.
235
+
236
+ % valid_verification_scope(+Scope)
237
+ valid_verification_scope(Scope) :- memberchk(Scope, [unit, integration, end_to_end]), !.
238
+
239
+ % valid_verification_perspective(+Perspective)
240
+ valid_verification_perspective(Perspective) :- memberchk(Perspective, [internal, consumer]), !.
143
241
 
144
242
  % exactly_one_value_field(+Props)
145
243
  exactly_one_value_field(Props) :-
@@ -2,6 +2,11 @@ import { createHash, randomUUID } from "node:crypto";
2
2
  import { appendFileSync, mkdirSync } from "node:fs";
3
3
  import path from "node:path";
4
4
 
5
+ import {
6
+ appendPayloadCountField,
7
+ normalizeResultPayload,
8
+ } from "./operations/result-envelope.js";
9
+
5
10
  export interface DiagnosticUsageInput {
6
11
  readonly workspaceRoot: string;
7
12
  readonly tool: string;
@@ -20,16 +25,6 @@ function isRecord(value: unknown): value is Record<string, unknown> {
20
25
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
21
26
  }
22
27
 
23
- function resultRecord(result: unknown): Record<string, unknown> | undefined {
24
- if (!isRecord(result)) return undefined;
25
- if (isRecord(result.structuredContent)) return result.structuredContent;
26
- // CLI JSON operations return the same versioned KibiResult envelope as MCP
27
- // structuredContent. Unwrap its data before deriving operation-specific
28
- // telemetry fields (coverage/proof fields in particular).
29
- if (result.kibiProtocol === 1 && isRecord(result.data)) return result.data;
30
- return result;
31
- }
32
-
33
28
  function stringArray(value: unknown): string[] {
34
29
  return Array.isArray(value)
35
30
  ? value.filter((item): item is string => typeof item === "string")
@@ -188,11 +183,7 @@ export function deriveDiagnosticUsageFields(
188
183
  }
189
184
  }
190
185
 
191
- const structured = resultRecord(result);
192
- const envelope =
193
- isRecord(structured) && structured.kibiProtocol === 1
194
- ? structured
195
- : undefined;
186
+ const { envelope, data: structured } = normalizeResultPayload(result);
196
187
  if (envelope) {
197
188
  fields.protocol_version = envelope.kibiProtocol;
198
189
  fields.result_version =
@@ -214,18 +205,19 @@ export function deriveDiagnosticUsageFields(
214
205
  fields.unsafe_original_retry = telemetry?.unsafe_original_retry === true;
215
206
  }
216
207
  if (tool === "kb_query" || tool === "kb_search") {
217
- const resultCount = Number(structured?.count ?? 0);
218
- fields.result_count = resultCount;
219
- fields.zero_results = resultCount === 0;
220
- fields.result_summary =
221
- resultCount === 0 ? "0 results" : `${resultCount} results`;
208
+ appendPayloadCountField(fields, "result_count", "results", structured);
209
+ if (typeof fields.result_count === "number") {
210
+ fields.zero_results = fields.result_count === 0;
211
+ }
222
212
  }
223
213
  if (tool === "kb_check") {
224
- const count = Number(structured?.count ?? 0);
225
- fields.violation_count = count;
214
+ appendPayloadCountField(
215
+ fields,
216
+ "violation_count",
217
+ "violations",
218
+ structured,
219
+ );
226
220
  fields.requested_rules = Array.isArray(args.rules) ? args.rules : [];
227
- fields.result_summary =
228
- count === 0 ? "0 violations" : `${count} violations`;
229
221
  }
230
222
  if (tool === "kb_coverage" && structured) {
231
223
  appendCoverageFields(fields, args, structured);
@@ -568,22 +568,10 @@ export async function loadKbExtractionResults(
568
568
  prolog.queryEntities.bind(prolog),
569
569
  );
570
570
  } else {
571
- const entityResult = await prolog.query(
572
- "findall([Id,Type,Props], kb_entity(Id, Type, Props), Results)",
573
- );
574
- if (entityResult.success) {
575
- entities = entityResult.bindings.Results
576
- ? parseListOfLists(entityResult.bindings.Results).map(
577
- parseEntityFromList,
578
- )
579
- : [];
580
- } else if (isOutputCapacityError(entityResult.error)) {
581
- entities = await loadBoundedEntityProjection(prolog);
582
- } else {
583
- throw new Error(
584
- `Full KB entity projection query failed: ${entityResult.error ?? "Unknown error"}`,
585
- );
586
- }
571
+ // Never probe with an unbounded all-entities findall: receipt histories
572
+ // make that answer grow without limit, and an overflow terminates the
573
+ // interactive Prolog process that serves every later query.
574
+ entities = await loadBoundedEntityProjection(prolog);
587
575
  }
588
576
  const relationships = new Map<string, ExtractionResult["relationships"]>();
589
577
 
@@ -31,6 +31,7 @@ import {
31
31
  partitionCheckFindings,
32
32
  qualityDiagnosticsFromImpact,
33
33
  resolveCheckRules,
34
+ stagedEntityIdStyleDiagnostics,
34
35
  } from "./check-helpers.js";
35
36
  import { executeStatus } from "./discovery-executors.js";
36
37
  import {
@@ -38,6 +39,7 @@ import {
38
39
  buildMigrationPlan,
39
40
  mergeMigrationPlans,
40
41
  } from "./migration-plan.js";
42
+ import { collectPredicateSchemaConformanceViolations } from "./predicate-schema-conformance.js";
41
43
  import type { OperationContext, PrologPort } from "./runtime-types.js";
42
44
  import { collectSourceRelationshipParityViolations } from "./source-relationship-parity.js";
43
45
  import type { OperationResult } from "./types.js";
@@ -136,7 +138,10 @@ export async function executeCheck(
136
138
  const rulesAllowlist = resolveCheckRules(args);
137
139
  const hasExplicitRules = args.rules !== undefined;
138
140
  const impactResult = await analyzeKbCheckImpact(workspaceRoot, args);
139
- const impactQualityDiagnostics = qualityDiagnosticsFromImpact(impactResult);
141
+ const impactQualityDiagnostics = [
142
+ ...qualityDiagnosticsFromImpact(impactResult),
143
+ ...stagedEntityIdStyleDiagnostics(workspaceRoot, args),
144
+ ];
140
145
  const maxDiagnosticsOption =
141
146
  args.maxDiagnostics !== undefined
142
147
  ? { maxDiagnostics: args.maxDiagnostics }
@@ -201,10 +206,16 @@ export async function executeCheck(
201
206
  )
202
207
  ? await collectSourceRelationshipParityViolations(workspaceRoot, prolog)
203
208
  : [];
209
+ const predicateConformanceFindings = rulesAllowlist.has(
210
+ "predicate-schema-conformance",
211
+ )
212
+ ? await collectPredicateSchemaConformanceViolations(prolog)
213
+ : [];
204
214
  const partitioned = partitionCheckFindings([
205
215
  ...aggregatedFindings,
206
216
  ...queryPlanViolations,
207
217
  ...sourceRelationshipParityViolations,
218
+ ...predicateConformanceFindings,
208
219
  ]);
209
220
  const violations: Violation[] = partitioned.violations;
210
221
 
@@ -1,3 +1,4 @@
1
+ import { execSync } from "node:child_process";
1
2
  import { readFileSync } from "node:fs";
2
3
  import { readFile } from "node:fs/promises";
3
4
  import path from "node:path";
@@ -20,6 +21,8 @@ import path from "node:path";
20
21
  */
21
22
  import { getKbPlPathOverride } from "../../env.js";
22
23
  import { resolveKbPlPath } from "../../prolog.js";
24
+ import { getStagedFiles } from "../../traceability/git-staged.js";
25
+ import { createStagedEntityIdStyleDiagnostics } from "../../traceability/staged-entity-id-style.js";
23
26
  import { analyzePrologQueryPlanSafety } from "../../utils/prolog-query-plan-safety.js";
24
27
  import {
25
28
  RULE_NAMES,
@@ -63,7 +66,7 @@ export function partitionCheckFindings(findings: readonly Violation[]): {
63
66
  const definition = getRuleDefinition(finding.rule);
64
67
  qualityDiagnostics.push({
65
68
  id: `rule.${finding.rule}`,
66
- severity: "warning",
69
+ severity: definition?.diagnosticSeverity ?? "warning",
67
70
  blocking: false,
68
71
  category: definition?.category ?? "integrity",
69
72
  ...(finding.entityId !== undefined ? { entityId: finding.entityId } : {}),
@@ -169,6 +172,29 @@ export async function analyzeKbCheckImpact(
169
172
  });
170
173
  }
171
174
 
175
+ /**
176
+ * Advisory naming-style review for entity Markdown staged as new. Runs only
177
+ * for `staged: true`, the creation boundary where a purely numeric ID can
178
+ * still be renamed cheaply; committed legacy entities are never evaluated.
179
+ */
180
+ // implements REQ-kibi-entity-id-style
181
+ export function stagedEntityIdStyleDiagnostics(
182
+ workspaceRoot: string,
183
+ args: Pick<CheckInput, "staged">,
184
+ ): readonly QualityDiagnostic[] {
185
+ if (args.staged !== true) return [];
186
+ try {
187
+ return createStagedEntityIdStyleDiagnostics(
188
+ getStagedFiles((command, options) =>
189
+ execSync(command, { ...options, cwd: workspaceRoot }),
190
+ ),
191
+ );
192
+ } catch {
193
+ // Outside a Git work tree there is no staged creation boundary.
194
+ return [];
195
+ }
196
+ }
197
+
172
198
  // implements REQ-mcp-tool-check
173
199
  export function qualityDiagnosticsFromImpact(
174
200
  impactResult: ChangedFileImpactResult | undefined,
@@ -172,6 +172,24 @@ export const OPERATION_DATA_SCHEMAS: Readonly<
172
172
  warnings: recordArray,
173
173
  migrationWarning: { type: ["string", "null"] },
174
174
  logic: recordValue,
175
+ vocabularyAlignment: objectData(
176
+ {
177
+ subject: recordValue,
178
+ redundancyCandidates: recordArray,
179
+ reviewPlan: recordArray,
180
+ stamps: recordArray,
181
+ fallbackUsed: booleanValue,
182
+ diagnostics: recordArray,
183
+ },
184
+ [
185
+ "subject",
186
+ "redundancyCandidates",
187
+ "reviewPlan",
188
+ "stamps",
189
+ "fallbackUsed",
190
+ "diagnostics",
191
+ ],
192
+ ),
175
193
  }),
176
194
  kb_suggest_predicates: objectData({
177
195
  text: stringValue,
@@ -256,6 +274,7 @@ export const OPERATION_DATA_SCHEMAS: Readonly<
256
274
  sourceWrites: recordArray,
257
275
  deletionPlan: recordValue,
258
276
  supersessionPlan: recordValue,
277
+ skippedEffects: stringArray,
259
278
  status: stringValue,
260
279
  effectFailures: recordArray,
261
280
  nextActions: recordArray,