kibi-cli 2.36.0 → 2.39.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 (224) hide show
  1. package/dist/cli-json-command.d.ts.map +1 -1
  2. package/dist/cli-json-command.js +4 -0
  3. package/dist/cli-operation-metadata.d.ts +1 -1
  4. package/dist/cli-operation-metadata.js +1 -1
  5. package/dist/cli-register-foundation.d.ts.map +1 -1
  6. package/dist/cli-register-foundation.js +2 -1
  7. package/dist/cli-register-maintenance.d.ts.map +1 -1
  8. package/dist/cli-register-maintenance.js +5 -0
  9. package/dist/cli-register-reporting.d.ts.map +1 -1
  10. package/dist/cli-register-reporting.js +1 -0
  11. package/dist/cli-validate.d.ts.map +1 -1
  12. package/dist/cli-validate.js +21 -2
  13. package/dist/cli.d.ts.map +1 -1
  14. package/dist/cli.js +19 -1
  15. package/dist/commands/aggregated-checks.d.ts.map +1 -1
  16. package/dist/commands/aggregated-checks.js +89 -16
  17. package/dist/commands/coverage.d.ts +1 -0
  18. package/dist/commands/coverage.d.ts.map +1 -1
  19. package/dist/commands/coverage.js +40 -0
  20. package/dist/commands/doctor.d.ts +5 -0
  21. package/dist/commands/doctor.d.ts.map +1 -1
  22. package/dist/commands/doctor.js +70 -35
  23. package/dist/commands/github-init.d.ts.map +1 -1
  24. package/dist/commands/github-init.js +4 -2
  25. package/dist/commands/hook-managers.d.ts +43 -0
  26. package/dist/commands/hook-managers.d.ts.map +1 -0
  27. package/dist/commands/hook-managers.js +426 -0
  28. package/dist/commands/init.d.ts +1 -0
  29. package/dist/commands/init.d.ts.map +1 -1
  30. package/dist/commands/init.js +40 -5
  31. package/dist/commands/migrate.d.ts.map +1 -1
  32. package/dist/commands/migrate.js +9 -3
  33. package/dist/commands/sync/persistence.d.ts.map +1 -1
  34. package/dist/commands/sync/persistence.js +49 -1
  35. package/dist/commands/telemetry.d.ts +7 -0
  36. package/dist/commands/telemetry.d.ts.map +1 -0
  37. package/dist/commands/telemetry.js +23 -0
  38. package/dist/decision-firmness.d.ts.map +1 -1
  39. package/dist/decision-firmness.js +11 -14
  40. package/dist/engine-limits.d.ts.map +1 -1
  41. package/dist/engine-limits.js +8 -10
  42. package/dist/entity-body-context.d.ts.map +1 -1
  43. package/dist/entity-body-context.js +39 -36
  44. package/dist/extractors/markdown.d.ts +6 -0
  45. package/dist/extractors/markdown.d.ts.map +1 -1
  46. package/dist/extractors/markdown.js +21 -0
  47. package/dist/extractors/symbol-coordinates.d.ts.map +1 -1
  48. package/dist/extractors/symbol-coordinates.js +23 -4
  49. package/dist/firm-decision-edit.d.ts.map +1 -1
  50. package/dist/firm-decision-edit.js +1 -3
  51. package/dist/intent-search.d.ts +5 -1
  52. package/dist/intent-search.d.ts.map +1 -1
  53. package/dist/intent-search.js +118 -33
  54. package/dist/logic/ir.d.ts.map +1 -1
  55. package/dist/logic/ir.js +82 -108
  56. package/dist/operations/bootstrap/discovery-evidence.d.ts.map +1 -1
  57. package/dist/operations/bootstrap/discovery-evidence.js +44 -2
  58. package/dist/operations/bootstrap/discovery.d.ts.map +1 -1
  59. package/dist/operations/bootstrap/discovery.js +1 -0
  60. package/dist/operations/bootstrap/guidance-actions.d.ts.map +1 -1
  61. package/dist/operations/bootstrap/guidance-actions.js +2 -1
  62. package/dist/operations/bootstrap/plugin-offers.d.ts +11 -2
  63. package/dist/operations/bootstrap/plugin-offers.d.ts.map +1 -1
  64. package/dist/operations/bootstrap/plugin-offers.js +48 -9
  65. package/dist/operations/proof/claim-bindings.d.ts.map +1 -1
  66. package/dist/operations/proof/claim-bindings.js +1 -0
  67. package/dist/operations/proof/code-certificates.d.ts +2 -0
  68. package/dist/operations/proof/code-certificates.d.ts.map +1 -1
  69. package/dist/operations/proof/code-certificates.js +34 -14
  70. package/dist/operations/proof/code-models.d.ts.map +1 -1
  71. package/dist/operations/proof/code-models.js +19 -5
  72. package/dist/operations/proof/code-runner.d.ts +16 -0
  73. package/dist/operations/proof/code-runner.d.ts.map +1 -1
  74. package/dist/operations/proof/code-runner.js +42 -6
  75. package/dist/operations/proof/explain.d.ts +63 -0
  76. package/dist/operations/proof/explain.d.ts.map +1 -1
  77. package/dist/operations/proof/explain.js +162 -0
  78. package/dist/operations/semantic-advisor/analyze-prose.d.ts +9 -1
  79. package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
  80. package/dist/operations/semantic-advisor/analyze-prose.js +21 -0
  81. package/dist/operations/semantic-advisor/case-preview.d.ts +24 -0
  82. package/dist/operations/semantic-advisor/case-preview.d.ts.map +1 -0
  83. package/dist/operations/semantic-advisor/case-preview.js +216 -0
  84. package/dist/operations/semantic-advisor/shared.d.ts.map +1 -1
  85. package/dist/operations/semantic-advisor/shared.js +3 -0
  86. package/dist/operations/semantic-advisor/types.d.ts +23 -0
  87. package/dist/operations/semantic-advisor/types.d.ts.map +1 -1
  88. package/dist/plugins/approved-source-analyzers.generated.d.ts +11 -8
  89. package/dist/plugins/approved-source-analyzers.generated.d.ts.map +1 -1
  90. package/dist/plugins/approved-source-analyzers.generated.js +11 -8
  91. package/dist/plugins/compose-search-hints.d.ts +29 -0
  92. package/dist/plugins/compose-search-hints.d.ts.map +1 -0
  93. package/dist/plugins/compose-search-hints.js +94 -0
  94. package/dist/plugins/external-allowlist.d.ts +7 -0
  95. package/dist/plugins/external-allowlist.d.ts.map +1 -1
  96. package/dist/plugins/external-allowlist.js +11 -0
  97. package/dist/plugins/registry.d.ts +8 -1
  98. package/dist/plugins/registry.d.ts.map +1 -1
  99. package/dist/plugins/registry.js +22 -3
  100. package/dist/plugins/source-classification.d.ts +2 -2
  101. package/dist/plugins/source-classification.d.ts.map +1 -1
  102. package/dist/plugins/source-classification.js +25 -1
  103. package/dist/prolog/codec.d.ts.map +1 -1
  104. package/dist/prolog/codec.js +10 -20
  105. package/dist/public/impact/coverage-depth-quality.d.ts.map +1 -1
  106. package/dist/public/impact/coverage-depth-quality.js +32 -16
  107. package/dist/public/impact/full-kb-quality.d.ts +6 -0
  108. package/dist/public/impact/full-kb-quality.d.ts.map +1 -1
  109. package/dist/public/impact/full-kb-quality.js +8 -3
  110. package/dist/public/impact/requirement-quality.d.ts.map +1 -1
  111. package/dist/public/impact/requirement-quality.js +56 -29
  112. package/dist/public/operations/catalog.d.ts +44 -4
  113. package/dist/public/operations/catalog.d.ts.map +1 -1
  114. package/dist/public/operations/check-executor.d.ts +6 -0
  115. package/dist/public/operations/check-executor.d.ts.map +1 -1
  116. package/dist/public/operations/check-executor.js +34 -2
  117. package/dist/public/operations/discovery-executors.d.ts +5 -1
  118. package/dist/public/operations/discovery-executors.d.ts.map +1 -1
  119. package/dist/public/operations/discovery-executors.js +65 -4
  120. package/dist/public/operations/evidence-floor.d.ts +8 -1
  121. package/dist/public/operations/evidence-floor.d.ts.map +1 -1
  122. package/dist/public/operations/evidence-floor.js +3 -4
  123. package/dist/public/operations/migration-plan.d.ts.map +1 -1
  124. package/dist/public/operations/migration-plan.js +41 -10
  125. package/dist/public/operations/node-ports.d.ts.map +1 -1
  126. package/dist/public/operations/node-ports.js +3 -1
  127. package/dist/public/operations/repair-plan.d.ts +46 -0
  128. package/dist/public/operations/repair-plan.d.ts.map +1 -1
  129. package/dist/public/operations/repair-plan.js +110 -1
  130. package/dist/public/operations/schema6-check-actions.js +1 -1
  131. package/dist/public/operations/source-analysis-cache.d.ts +22 -0
  132. package/dist/public/operations/source-analysis-cache.d.ts.map +1 -0
  133. package/dist/public/operations/source-analysis-cache.js +157 -0
  134. package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
  135. package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
  136. package/dist/public/operations/specs/check-rules.generated.js +2 -1
  137. package/dist/public/operations/specs/check.d.ts +1 -1
  138. package/dist/public/operations/specs/discovery.d.ts +7 -2
  139. package/dist/public/operations/specs/discovery.d.ts.map +1 -1
  140. package/dist/public/operations/specs/discovery.js +7 -2
  141. package/dist/public/operations/specs/mutation-schemas.d.ts +36 -1
  142. package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
  143. package/dist/public/operations/specs/mutation-schemas.js +30 -0
  144. package/dist/public/operations/specs/upsert.d.ts +36 -1
  145. package/dist/public/operations/specs/upsert.d.ts.map +1 -1
  146. package/dist/public/operations/symbol-granularity-check.d.ts +3 -1
  147. package/dist/public/operations/symbol-granularity-check.d.ts.map +1 -1
  148. package/dist/public/operations/symbol-granularity-check.js +21 -7
  149. package/dist/public/proof-protocol.d.ts +6 -1
  150. package/dist/public/proof-protocol.d.ts.map +1 -1
  151. package/dist/public/proof-protocol.js +12 -3
  152. package/dist/public/proof-sources.d.ts +2 -0
  153. package/dist/public/proof-sources.d.ts.map +1 -1
  154. package/dist/public/proof-sources.js +32 -6
  155. package/dist/public/schemas/entity.d.ts.map +1 -1
  156. package/dist/public/schemas/entity.js +59 -0
  157. package/dist/public/skills/kibi-bootstrap/SKILL.md +2 -2
  158. package/dist/public/skills/kibi-commit-review/SKILL.md +6 -2
  159. package/dist/public/skills/kibi-decisions/SKILL.md +7 -2
  160. package/dist/public/skills/kibi-decisions/resources/signoff-views.md +3 -1
  161. package/dist/public/skills/kibi-usage/SKILL.md +50 -3
  162. package/dist/public/skills/kibi-usage/resources/fact-lanes.md +34 -0
  163. package/dist/public/skills/kibi-usage/resources/proof.md +13 -5
  164. package/dist/public/skills/kibi-usage/resources/workflows.md +10 -0
  165. package/dist/relationships/shards.d.ts +2 -0
  166. package/dist/relationships/shards.d.ts.map +1 -1
  167. package/dist/relationships/shards.js +25 -1
  168. package/dist/schemas/entity.schema.json +98 -1
  169. package/dist/search-answer.d.ts +3 -2
  170. package/dist/search-answer.d.ts.map +1 -1
  171. package/dist/search-answer.js +57 -4
  172. package/dist/search-hints.d.ts +58 -0
  173. package/dist/search-hints.d.ts.map +1 -0
  174. package/dist/search-hints.js +187 -0
  175. package/dist/search-ranking.d.ts +7 -0
  176. package/dist/search-ranking.d.ts.map +1 -1
  177. package/dist/search-ranking.js +54 -56
  178. package/dist/search-token-cache.d.ts +30 -0
  179. package/dist/search-token-cache.d.ts.map +1 -0
  180. package/dist/search-token-cache.js +86 -0
  181. package/dist/traceability/impact-knowledge.d.ts.map +1 -1
  182. package/dist/traceability/impact-knowledge.js +2 -0
  183. package/dist/traceability/temp-kb.d.ts.map +1 -1
  184. package/dist/traceability/temp-kb.js +11 -1
  185. package/dist/types/entities.d.ts +12 -0
  186. package/dist/types/entities.d.ts.map +1 -1
  187. package/dist/usage-telemetry.d.ts +20 -0
  188. package/dist/usage-telemetry.d.ts.map +1 -0
  189. package/dist/usage-telemetry.js +93 -0
  190. package/dist/utils/branch-resolver.d.ts.map +1 -1
  191. package/dist/utils/branch-resolver.js +1 -0
  192. package/dist/utils/rule-registry.generated.d.ts +5 -0
  193. package/dist/utils/rule-registry.generated.d.ts.map +1 -1
  194. package/dist/utils/rule-registry.generated.js +6 -0
  195. package/package.json +5 -4
  196. package/schema/entities.pl +12 -0
  197. package/src/public/impact/coverage-depth-quality.ts +59 -21
  198. package/src/public/impact/full-kb-quality.ts +15 -1
  199. package/src/public/impact/requirement-quality.ts +95 -38
  200. package/src/public/operations/check-executor.ts +41 -1
  201. package/src/public/operations/discovery-executors.ts +92 -4
  202. package/src/public/operations/evidence-floor.ts +15 -3
  203. package/src/public/operations/migration-plan.ts +41 -9
  204. package/src/public/operations/node-ports.ts +3 -1
  205. package/src/public/operations/repair-plan.ts +152 -1
  206. package/src/public/operations/schema6-check-actions.ts +1 -1
  207. package/src/public/operations/source-analysis-cache.ts +196 -0
  208. package/src/public/operations/specs/check-rules.generated.ts +2 -1
  209. package/src/public/operations/specs/discovery.ts +8 -2
  210. package/src/public/operations/specs/mutation-schemas.ts +34 -0
  211. package/src/public/operations/symbol-granularity-check.ts +25 -5
  212. package/src/public/proof-protocol-types.d.ts +1 -1
  213. package/src/public/proof-protocol.ts +18 -4
  214. package/src/public/proof-sources.ts +37 -6
  215. package/src/public/schemas/entity.ts +65 -0
  216. package/src/public/skills/kibi-bootstrap/SKILL.md +2 -2
  217. package/src/public/skills/kibi-commit-review/SKILL.md +6 -2
  218. package/src/public/skills/kibi-decisions/SKILL.md +7 -2
  219. package/src/public/skills/kibi-decisions/resources/signoff-views.md +3 -1
  220. package/src/public/skills/kibi-usage/SKILL.md +50 -3
  221. package/src/public/skills/kibi-usage/resources/fact-lanes.md +34 -0
  222. package/src/public/skills/kibi-usage/resources/proof.md +13 -5
  223. package/src/public/skills/kibi-usage/resources/workflows.md +10 -0
  224. package/src/schemas/entity.schema.json +98 -1
@@ -2,7 +2,7 @@
2
2
  id: kibi-commit-review
3
3
  name: kibi-commit-review
4
4
  description: "Use when kibi check --staged or the Kibi pre-commit hook blocks a commit (kibi_impact_evidence_missing, symbols_manifest_stale, symbol_granularity_violation, symbol-coverage, kibi check-generated drift, Staged impact review failed), or when preparing a commit or pull-request impact review. Covers reading the per-file Detail lines, authoring .kb/symbols.yaml symbol entries through kb_upsert, staging the tracked Kibi evidence with git add (symbol coordinates are derived and never staged), kb_prepare_impact_review for a staged or diff scope, the kibi signoff requirements summary to show before a commit, and how merge commits and migration renames are judged."
5
- version: 1.3.0
5
+ version: 1.4.0
6
6
  kibiCompatibility: ">=1.0.0"
7
7
  tags:
8
8
  - kibi
@@ -91,7 +91,11 @@ apps); never attach the `.html` as a file, which chat apps show as raw source;
91
91
  past 15 requirements the Markdown stops and only the page lists them all.
92
92
  Host details: `kibi-decisions`, `resources/signoff-views.md`. `--no-proof` skips the proof lookup, which reads coverage and is slow
93
93
  on a large knowledge base. The summary is not an approval: never set
94
- `approved_by` or `origin.ref` from it.
94
+ `approved_by` or `origin.ref` from it. Show it before you open or merge the
95
+ pull request. When the person answers, record their answer in the same
96
+ change (their name in `approved_by`, their words in `origin.ref` or
97
+ `approval_ref`) and push it to the same pull request; never move a signoff,
98
+ firmness or waiver approval into a separate pull request.
95
99
 
96
100
  ## Impact reviews
97
101
 
@@ -2,7 +2,7 @@
2
2
  id: kibi-decisions
3
3
  name: kibi-decisions
4
4
  description: "Use when the person states a rule or decision (must, never, always, from now on, we decided), when a Kibi hook asks to confirm or warns about an edit to code that implements a firm requirement, when the Stop hook says source files changed but nothing was recorded, when kb_check quotes requirement_statement_unverified, or when a request conflicts with a recorded requirement or ADR. Covers reading firmness and origin, recording a person's rule as firm with origin.ref, superseding with a Why this changed section, the kb_compile_intent unresolved/reviewCandidates/conflictReviews loop, asking before overriding a firm rule, and putting decisions to the person as one numbered kibi signoff --questions view."
5
- version: 1.4.0
5
+ version: 1.5.0
6
6
  kibiCompatibility: ">=1.0.0"
7
7
  tags:
8
8
  - kibi
@@ -115,7 +115,12 @@ again until none is open, then record each rule with their words in
115
115
  `origin.ref`. Fields and outputs: `resources/signoff-views.md`.
116
116
 
117
117
  Never invent words for `origin.ref`, never set `approved_by` yourself, and
118
- mark your own picks `default` and guesses `exploratory`. Payload shapes,
118
+ mark your own picks `default` and guesses `exploratory`. Once the person has
119
+ answered, recording their answer (their name in `approved_by` or a
120
+ `*_waiver_approved_by` field, their words in `origin.ref` or `approval_ref`)
121
+ is yours to do: put it on the branch of the change it approves and push it to
122
+ that pull request, never to a separate one. Ask before you open or merge the
123
+ pull request, so the answer lands in it. Payload shapes,
119
124
  refusal messages and the `kb_compile_intent` review loop are in
120
125
  `resources/decision-records.md`.
121
126
 
@@ -51,7 +51,9 @@ writes and opens the page; `--format json` prints the view.
51
51
  The person answers by number ("1 yes, 2 exploratory, 3 reword: ..."). Copy
52
52
  each answer into `answer`, render again, and record the rules only once every
53
53
  question is answered. An answer is the person's words: quote it in
54
- `origin.ref`; a view itself is never an approval.
54
+ `origin.ref`; a view itself is never an approval. Record the answers on the
55
+ branch of the change they approve and push them to its pull request, never to
56
+ a separate one.
55
57
 
56
58
  ## Summary contents
57
59
 
@@ -2,7 +2,7 @@
2
2
  id: kibi-usage
3
3
  name: Kibi Usage
4
4
  description: Use Kibi's source-first, exact-Git, migration-aware, proof-aware operations safely across MCP or the trusted local CLI, including partial completion repair.
5
- version: 2.32.0
5
+ version: 2.37.0
6
6
  kibiCompatibility: ">=1.0.0"
7
7
  tags:
8
8
  - kibi
@@ -137,7 +137,9 @@ For an edit that keeps the governing rule, limit the consultation before the edi
137
137
  `unknown`, or `none`, which is not proof), the `exceptions` that exempt it,
138
138
  and the `unknowns` the checks could not decide. Those links and verdicts are
139
139
  discovery, not proof. Pass `sourceLocations` before changing a source file,
140
- and `rankingMode: "legacy"` for literal identifier lookups. See
140
+ and `rankingMode: "legacy"` for literal identifier lookups. A weak answer
141
+ may add `queryAnalysis.hints` (requirements the question may mean): re-ask
142
+ in their words, never cite a hint as the rule. See
141
143
  `resources/workflows.md` for the mode recipe.
142
144
  2. Resolve genuine ambiguity with the human; use `kb_model` for deterministic
143
145
  interpretation and typed facts.
@@ -286,7 +288,9 @@ authored. Each one is the order the write path accepts.
286
288
  its scenario: `specified_by` (req → scenario) is sent in the
287
289
  requirement's write, never in the scenario's, so create the scenario
288
290
  first, with `assumes` links (scenario → `property_value` fact, sent in
289
- the scenario's own write) to the values its outcome relies on. Set
291
+ the scenario's own write) to the values its outcome relies on; add a
292
+ rejection scenario that assumes a forbidden value next to the success
293
+ one (see Quantified claims below). Set
290
294
  `expects` only on a scenario that has `assumes` links; `expects: success`
291
295
  without them only yields `scenario-feasibility-unknown` ("assumes
292
296
  nothing"). A
@@ -368,6 +372,14 @@ human sets `approved_by`; `kb_check` flags approvals an agent recorded without
368
372
  corroboration. Never fill in an approval yourself. Record why a requirement
369
373
  exists in `rationale`, or link the ADR that explains it.
370
374
 
375
+ A signoff belongs to the change it approves. Ask for it before you open or
376
+ merge the pull request, and when the person answers, record their answer
377
+ (`approved_by` or a `*_waiver_approved_by` field set to them, their words in
378
+ `origin.ref` or `approval_ref`) on the same branch and push it to the same pull
379
+ request. Writing down an answer the person gave is not approving it yourself.
380
+ Never open a separate pull request only to carry a signoff, firmness or waiver
381
+ approval.
382
+
371
383
  ## Decision firmness
372
384
 
373
385
  Requirements and ADRs carry `firmness`, which says what you may do with them.
@@ -442,6 +454,41 @@ predicate bound with `harness_for` (scope `harness`) also counts toward
442
454
  `proved`; an intent-scope binding stays `tested`. When the `evidence-floor` rule fails, follow Debugging
443
455
  proof regressions in `resources/proof.md` and use `kibi proof explain`.
444
456
 
457
+ ## Quantified claims: model the dimension
458
+
459
+ When a claim says every, each, all, any, only, at least, at most, exactly, a
460
+ role, a status or a count, ground it on what varies, never on `= true`: an int
461
+ count or bound (`role_count eq 1`, `uninstrumented_loaded_files eq 0`), a set,
462
+ or a typed rule with a `forall` variable. Keep `value_type: bool` for genuinely
463
+ binary properties (a flag is on). A `shadow_analysis` cue from `kb_model`
464
+ (`mode: "analyze"`) with `kind: quantifier` or `numeric` and `represented:
465
+ false` means the planned grounding hides the dimension. When
466
+ `mode: "predicates"` finds no schema for such a claim, do not stop at the
467
+ ontology-gap observation: call `kb_model` with `mode: "requirement"` and an
468
+ int `subjectKey`/`propertyKey`/`operator`/`value` for the count, and keep the
469
+ gap only when no count, set or rule expresses the claim.
470
+
471
+ Specify the requirement with scenarios that carry their inputs. Each scenario
472
+ sets `expects` and `assumes` its own `property_value` fact: same `subject_key`
473
+ and `property_key` as the grounding, with the scenario's value. These
474
+ assumed-value facts are linked only by the scenario's `assumes`, never by the
475
+ requirement, so a forbidden value does not contradict the grounding; it is
476
+ what makes the scenario a rejection. Write at least:
477
+
478
+ - a success scenario assuming an allowed value (`expects: success`);
479
+ - a rejection scenario assuming a forbidden value (`expects: rejection`, or
480
+ `error`); a scenario that only describes the refusal in prose, without
481
+ `expects` and `assumes`, does not count;
482
+ - for a quantified claim, cases at zero, one and many when they differ.
483
+
484
+ ```json
485
+ {"type":"fact","id":"FACT-member-role-count-2","properties":{"title":"Member holds two roles","status":"active","fact_kind":"property_value","subject_key":"organization.member","property_key":"role_count","operator":"eq","value_type":"int","value_int":2}}
486
+ {"type":"scenario","id":"SCEN-member-two-roles-rejected","properties":{"title":"A member with two roles is rejected","status":"active","expects":"rejection"},"relationships":[{"type":"assumes","from":"SCEN-member-two-roles-rejected","to":"FACT-member-role-count-2"}]}
487
+ ```
488
+
489
+ Then send `specified_by` to every scenario in the requirement's write.
490
+ Details: `resources/fact-lanes.md`, Model the Dimension, Not the Verdict.
491
+
445
492
  ## Predicate Ontology Decision Tree
446
493
 
447
494
  Call `kb_model` with `mode: "analyze"` on the complete prose before encoding a clause.
@@ -15,6 +15,40 @@ Use the advisor-returned atomic inventory as the identity boundary. Trailing pun
15
15
 
16
16
  Example compound prose: “Checkout requires payment authorization before order submission, and customer data must be retained for 7 years.” This is two claims, not one. The first becomes `dependency_rule(checkout,payment_authorization,order_submission)`; the second becomes a strict retention property. Both fact records carry different advisor-issued claim keys, and both keys appear in the requirement manifest. A single `requires_predicate` edge is incomplete.
17
17
 
18
+ ## Model the Dimension, Not the Verdict
19
+
20
+ A claim that says every, each, all, any, only, at least, at most, exactly, no more than, a role, a status or a count ranges over something. Ground it on the thing that varies, not on a boolean that says the claim holds:
21
+
22
+ | The claim varies over | Ground it on |
23
+ | --- | --- |
24
+ | a count or bound ("at most 5 owners", "exactly one role") | `property_value` with `value_type: int` and `eq`/`lte`/`gte` |
25
+ | each member of a collection ("every loaded file") | an int count of the members that break the rule (`eq 0`), or a typed rule with a `forall` variable over the member |
26
+ | a closed set of values ("only admins and owners") | a canonical string set, or a predicate argument with `argument_constants` |
27
+ | a status or lifecycle ("a closed invoice cannot reopen") | a typed rule over the status, or a `state_machine` proof |
28
+
29
+ Use `value_type: bool` (`= true`) only when the property itself is binary: a flag is on, a feature is enabled. `module.loader.instruments_all_loaded_files = true` restates the claim and gives Kibi nothing that can vary: no boundary, no zero/one/many case, and no contradiction with another requirement that bounds the same count.
30
+
31
+ `kb_model` (`mode: "analyze"`) lists `shadow_analysis` cues. A `quantifier` or `numeric` cue with `represented: false` means the grounding does not carry the dimension yet. Do not ignore it: re-plan the grounding as a count, a rule variable or a set before writing. When no typed shape fits, keep the clause `ontology_gap` rather than downgrading it to a boolean verdict.
32
+
33
+ Example: "Each organization member must hold exactly one role."
34
+
35
+ ```yaml
36
+ # Avoid: the verdict
37
+ - { fact_kind: property_value, subject_key: organization.member, property_key: holds_exactly_one_role, operator: eq, value_type: bool, value_bool: true }
38
+ # Prefer: the dimension
39
+ - { fact_kind: property_value, subject_key: organization.member, property_key: role_count, operator: eq, value_type: int, value_int: 1 }
40
+ ```
41
+
42
+ ### Scenarios carry their inputs
43
+
44
+ A requirement grounded on a dimension is specified by scenarios that pick values of it. Each scenario `assumes` the `property_value` facts that state its input (same `subject_key` and `property_key` as the requirement's grounding, with the scenario's value) and sets `expects`:
45
+
46
+ - one success scenario whose assumed value the requirement allows (`role_count = 1`, `expects: success`);
47
+ - at least one rejection or error scenario whose assumed value the requirement forbids (`role_count = 2`, `expects: rejection`): a requirement that constrains behavior is not specified by its happy path alone;
48
+ - for a quantified claim, scenarios at zero, one and many of the varying thing whenever those behave differently (no files loaded, one file, several files).
49
+
50
+ Assumed-value facts are ordinary `property_value` facts linked only by the scenario's `assumes`; never link them from the requirement. Only requirement-linked facts are compared for contradictions, so an assumed forbidden value (`role_count = 2` next to the grounding `role_count eq 1`) is not a conflict: it is the input that makes the scenario a rejection. A refusal described only in prose, without `expects` and `assumes`, does not specify anything Kibi can check. Create them and the scenarios before the requirement write that sends `specified_by`. `scenario-feasibility` then checks every success scenario against the requirement, and the `happy_path_only` proof gap reports a requirement none of whose scenarios expects rejection or error while assuming a value that opposes one of its claims.
51
+
18
52
  ## Predicate Lane (Relational Claims)
19
53
 
20
54
  Call `kb_model` with `mode: "analyze"`, then with `mode: "predicates"`. Apply a candidate only when its schema meaning and ordered arguments fit the claim. Use the returned `applyPlan` rather than hand-writing unsupported predicate names, and link the requirement to the predicate fact with `requires_predicate`.
@@ -173,7 +173,10 @@ left:
173
173
  Enum values, dict keys, list/tuple/set items) and rejects a
174
174
  certificate that does not cover exactly its members, so a hand-listed or
175
175
  partial domain stays `tested`. An import from build output is mapped back
176
- to its source through `tsconfig.json` `outDir`/`rootDir`.
176
+ to its source through `tsconfig.json` `outDir`/`rootDir`. For a list of
177
+ records (a catalog), add `field: <name>` and pass
178
+ `key: (item) => item.<name>` to `exhaustiveCertificate`; the members are
179
+ that field's values.
177
180
  - `typecheck`: a witness file that stops compiling when a domain member
178
181
  goes unhandled (a switch ending in a `never` assignment, or a
179
182
  `satisfies Record<Domain, ...>` map). Set `witness.path` and
@@ -195,7 +198,8 @@ left:
195
198
  evaluates the number export itself and adds `variable eq value` as an
196
199
  assumption. For a count claim over a collection ("exactly 32 tools") add
197
200
  `measure: count` and name the list, set, map or object export; Kibi uses
198
- its size, so do not add a number export just for the proof. A count
201
+ its size, so do not add a number export just for the proof. A dotted
202
+ export (`POLICY.eventLimit`) reads one field of an object export. A count
199
203
  claim needs only `value_source`. Naming the claim's own fact in
200
204
  `constraint_source` assumes the claim: without `value_source` Kibi counts
201
205
  that derivation as intent only (tested), and with it a code value that
@@ -244,7 +248,7 @@ left:
244
248
  `subset_of` and `excludes`. Rules over a machine use `transition`,
245
249
  `reachable`, `initial`, `terminal`, `state`.
246
250
  - `regex`: set `pattern_source` to a `RegExp`, a Python `re.compile(...)` or
247
- a string constant. Model "X must match `re`" as a string fact with
251
+ a string constant (`export: BRAND.name` reads one field of an object). Model "X must match `re`" as a string fact with
248
252
  `operator: matches` (a JavaScript pattern with the `u` flag, matched
249
253
  whole); Kibi decides exact language equality and reports the shortest
250
254
  string only one side accepts. Backreferences, lookaround, `\b`, the `g`,
@@ -254,7 +258,8 @@ left:
254
258
  - `source`: Kibi reads a project source itself and checks a set fact
255
259
  against what it read, so the test only runs the proof (it may write
256
260
  nothing, or `sourceCertificate({ testId })`). Set `source: {reader, ...}`:
257
- `json`/`yaml` (`file`, `path`, `select`), `glob` (`pattern`, `capture`),
261
+ `json`/`yaml` (`file`, `path`, `select`, `field` to read one key of
262
+ each list item, such as the `run` of each workflow step), `glob` (`pattern`, `capture`),
258
263
  `openapi` (`file`, `select: operations|unsecured_operations|...`),
259
264
  `references` (`files`, `extract: env|imports|calls|string_args|thrown|
260
265
  property`), `schema` (`format: drizzle|prisma|sql`, `select:
@@ -271,7 +276,10 @@ left:
271
276
  `nullable_fields` (only `eq`/`includes`) with bare members `name` for
272
277
  "every table" (it also covers tables added later) or `table.name` for
273
278
  one; `middleware` with `includes` for "every route under /p must use M"
274
- (Kibi checks each route). Name middleware with `names_from`: a
279
+ (Kibi checks each route); `precedes` with `includes` and members
280
+ `"A -> B"` for an order in a list ("the gate runs before the push"):
281
+ A and B are both in the list and every A comes before every B. Name
282
+ middleware with `names_from`: a
275
283
  zero-argument factory export such as `requireAuth()` names the
276
284
  middleware it returns `requireAuth`. Write the fact with `kb_model`
277
285
  (requirement mode, `operator` plus a list `value`) or `kb_upsert`. The
@@ -78,6 +78,16 @@ no-answer, so widen the query or drop to lexical search rather than treating it
78
78
  as "nothing exists". A literal identifier lookup is still best served
79
79
  lexically.
80
80
 
81
+ When the project activates a `kibi.search-hints.v1` plugin (for example
82
+ `kibi-plugin-search-hints`), a weak or abstained intent answer also carries
83
+ `queryAnalysis.hints`: up to ten current requirements the question may mean,
84
+ found by meaning rather than shared words, each with a `score` and, when it
85
+ was reached through a scenario, test or fact, that entity as `via`. Hints are
86
+ suggestions, never governing requirements, and they never change the results
87
+ or the answer layer. Re-ask `kb_search` in the words of a hint that fits, or
88
+ pass them as `semanticFacets.aliases`, then read the requirement with
89
+ `kb_query`; never cite a hint as the rule. `hints: false` turns them off.
90
+
81
91
  On the first page, intent mode also returns an answer layer in `data.answer`
82
92
  (`kibi.search-answer.v1`; turn it off with `answer: false`):
83
93
 
@@ -562,6 +562,18 @@
562
562
  "minLength": 1,
563
563
  "description": "Requirement-only. Optional reference to the approval decision record (ticket, ADR or review link) for an exception requirement."
564
564
  },
565
+ "failure_side_waiver": {
566
+ "type": "string",
567
+ "minLength": 1,
568
+ "pattern": "\\S",
569
+ "description": "Requirement-only. Why the requirement has no failure side to test: its claims state a capability or an output shape, so there is no input or attempt for Kibi to refuse. Waives the happy_path_only gap once failure_side_waiver_approved_by is set."
570
+ },
571
+ "failure_side_waiver_approved_by": {
572
+ "type": "string",
573
+ "minLength": 1,
574
+ "pattern": "\\S",
575
+ "description": "Requirement-only. The person who accepted failure_side_waiver. Without it the waiver is reported as awaiting approval and the gap stays open."
576
+ },
565
577
  "rationale": {
566
578
  "type": "string",
567
579
  "minLength": 1,
@@ -684,6 +696,32 @@
684
696
  },
685
697
  "reason": {
686
698
  "type": "string"
699
+ },
700
+ "dimension": {
701
+ "type": "object",
702
+ "required": [
703
+ "quantifier",
704
+ "rewrites"
705
+ ],
706
+ "properties": {
707
+ "quantifier": {
708
+ "type": "string",
709
+ "minLength": 1
710
+ },
711
+ "rewrites": {
712
+ "type": "array",
713
+ "items": {
714
+ "type": "string",
715
+ "enum": [
716
+ "bound",
717
+ "rule",
718
+ "count",
719
+ "set"
720
+ ]
721
+ }
722
+ }
723
+ },
724
+ "additionalProperties": false
687
725
  }
688
726
  },
689
727
  "additionalProperties": false
@@ -831,6 +869,11 @@
831
869
  "type": "string",
832
870
  "minLength": 1,
833
871
  "description": "The name the domain is exported under in the symbol's source file, when the symbol's title is not that name."
872
+ },
873
+ "field": {
874
+ "type": "string",
875
+ "minLength": 1,
876
+ "description": "exhaustive: when the export is a list of records, the field of each record that names a domain member (a catalog's name)."
834
877
  }
835
878
  },
836
879
  "additionalProperties": false
@@ -861,7 +904,7 @@
861
904
  },
862
905
  "value_source": {
863
906
  "type": "array",
864
- "description": "arithmetic and smt: code constants the assumptions read. Kibi evaluates each export at ingest and requires the certificate to assume the variable equals that value, so the proof is about the code and not only the knowledge base. With measure count the value is the size of a list, set, map or object export, so a count claim reads the collection itself. An entry {source, measure: count} counts the members Kibi reads from a project source (routes, tables, environment variables).",
907
+ "description": "arithmetic and smt: code constants the assumptions read. Kibi evaluates each export at ingest and requires the certificate to assume the variable equals that value, so the proof is about the code and not only the knowledge base. With measure count the value is the size of a list, set, map or object export, so a count claim reads the collection itself. A dotted export (POLICY.eventLimit) reads one field of an object export. An entry {source, measure: count} counts the members Kibi reads from a project source (routes, tables, environment variables).",
865
908
  "minItems": 1,
866
909
  "items": {
867
910
  "type": "object",
@@ -1597,6 +1640,30 @@
1597
1640
  "claim_text": {
1598
1641
  "type": "string"
1599
1642
  },
1643
+ "dimension_waiver": {
1644
+ "type": "string",
1645
+ "minLength": 1,
1646
+ "pattern": "\\S",
1647
+ "description": "Fact-only. Why the quantifier word in claim_text (each, every, all, or a cardinality bound) ranges over nothing, so the claim needs no count, set or rule. Waives dimension_unrepresented for the claim once dimension_waiver_approved_by is set."
1648
+ },
1649
+ "dimension_waiver_approved_by": {
1650
+ "type": "string",
1651
+ "minLength": 1,
1652
+ "pattern": "\\S",
1653
+ "description": "Fact-only. The person who accepted dimension_waiver. Without it the waiver is reported as awaiting approval and the gap stays open."
1654
+ },
1655
+ "case_waiver": {
1656
+ "type": "string",
1657
+ "minLength": 1,
1658
+ "pattern": "\\S",
1659
+ "description": "Fact-only. Why the edge cases Kibi derives from this fact (the value past a bound, a value outside a set) are covered some other way or cannot occur. Waives uncovered_case for the fact once case_waiver_approved_by is set."
1660
+ },
1661
+ "case_waiver_approved_by": {
1662
+ "type": "string",
1663
+ "minLength": 1,
1664
+ "pattern": "\\S",
1665
+ "description": "Fact-only. The person who accepted case_waiver. Without it the waiver is reported as awaiting approval and the gap stays open."
1666
+ },
1600
1667
  "predicate_name": {
1601
1668
  "type": "string"
1602
1669
  },
@@ -1834,6 +1901,26 @@
1834
1901
  "claim_text"
1835
1902
  ]
1836
1903
  },
1904
+ {
1905
+ "required": [
1906
+ "dimension_waiver"
1907
+ ]
1908
+ },
1909
+ {
1910
+ "required": [
1911
+ "dimension_waiver_approved_by"
1912
+ ]
1913
+ },
1914
+ {
1915
+ "required": [
1916
+ "case_waiver"
1917
+ ]
1918
+ },
1919
+ {
1920
+ "required": [
1921
+ "case_waiver_approved_by"
1922
+ ]
1923
+ },
1837
1924
  {
1838
1925
  "required": [
1839
1926
  "predicate_name"
@@ -2046,6 +2133,16 @@
2046
2133
  "approval_ref"
2047
2134
  ]
2048
2135
  },
2136
+ {
2137
+ "required": [
2138
+ "failure_side_waiver"
2139
+ ]
2140
+ },
2141
+ {
2142
+ "required": [
2143
+ "failure_side_waiver_approved_by"
2144
+ ]
2145
+ },
2049
2146
  {
2050
2147
  "required": [
2051
2148
  "rationale"