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.
- package/dist/cli-json-command.d.ts.map +1 -1
- package/dist/cli-json-command.js +4 -0
- package/dist/cli-operation-metadata.d.ts +1 -1
- package/dist/cli-operation-metadata.js +1 -1
- package/dist/cli-register-foundation.d.ts.map +1 -1
- package/dist/cli-register-foundation.js +2 -1
- package/dist/cli-register-maintenance.d.ts.map +1 -1
- package/dist/cli-register-maintenance.js +5 -0
- package/dist/cli-register-reporting.d.ts.map +1 -1
- package/dist/cli-register-reporting.js +1 -0
- package/dist/cli-validate.d.ts.map +1 -1
- package/dist/cli-validate.js +21 -2
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +19 -1
- package/dist/commands/aggregated-checks.d.ts.map +1 -1
- package/dist/commands/aggregated-checks.js +89 -16
- package/dist/commands/coverage.d.ts +1 -0
- package/dist/commands/coverage.d.ts.map +1 -1
- package/dist/commands/coverage.js +40 -0
- package/dist/commands/doctor.d.ts +5 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +70 -35
- package/dist/commands/github-init.d.ts.map +1 -1
- package/dist/commands/github-init.js +4 -2
- package/dist/commands/hook-managers.d.ts +43 -0
- package/dist/commands/hook-managers.d.ts.map +1 -0
- package/dist/commands/hook-managers.js +426 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +40 -5
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +9 -3
- package/dist/commands/sync/persistence.d.ts.map +1 -1
- package/dist/commands/sync/persistence.js +49 -1
- package/dist/commands/telemetry.d.ts +7 -0
- package/dist/commands/telemetry.d.ts.map +1 -0
- package/dist/commands/telemetry.js +23 -0
- package/dist/decision-firmness.d.ts.map +1 -1
- package/dist/decision-firmness.js +11 -14
- package/dist/engine-limits.d.ts.map +1 -1
- package/dist/engine-limits.js +8 -10
- package/dist/entity-body-context.d.ts.map +1 -1
- package/dist/entity-body-context.js +39 -36
- package/dist/extractors/markdown.d.ts +6 -0
- package/dist/extractors/markdown.d.ts.map +1 -1
- package/dist/extractors/markdown.js +21 -0
- package/dist/extractors/symbol-coordinates.d.ts.map +1 -1
- package/dist/extractors/symbol-coordinates.js +23 -4
- package/dist/firm-decision-edit.d.ts.map +1 -1
- package/dist/firm-decision-edit.js +1 -3
- package/dist/intent-search.d.ts +5 -1
- package/dist/intent-search.d.ts.map +1 -1
- package/dist/intent-search.js +118 -33
- package/dist/logic/ir.d.ts.map +1 -1
- package/dist/logic/ir.js +82 -108
- package/dist/operations/bootstrap/discovery-evidence.d.ts.map +1 -1
- package/dist/operations/bootstrap/discovery-evidence.js +44 -2
- package/dist/operations/bootstrap/discovery.d.ts.map +1 -1
- package/dist/operations/bootstrap/discovery.js +1 -0
- package/dist/operations/bootstrap/guidance-actions.d.ts.map +1 -1
- package/dist/operations/bootstrap/guidance-actions.js +2 -1
- package/dist/operations/bootstrap/plugin-offers.d.ts +11 -2
- package/dist/operations/bootstrap/plugin-offers.d.ts.map +1 -1
- package/dist/operations/bootstrap/plugin-offers.js +48 -9
- package/dist/operations/proof/claim-bindings.d.ts.map +1 -1
- package/dist/operations/proof/claim-bindings.js +1 -0
- package/dist/operations/proof/code-certificates.d.ts +2 -0
- package/dist/operations/proof/code-certificates.d.ts.map +1 -1
- package/dist/operations/proof/code-certificates.js +34 -14
- package/dist/operations/proof/code-models.d.ts.map +1 -1
- package/dist/operations/proof/code-models.js +19 -5
- package/dist/operations/proof/code-runner.d.ts +16 -0
- package/dist/operations/proof/code-runner.d.ts.map +1 -1
- package/dist/operations/proof/code-runner.js +42 -6
- package/dist/operations/proof/explain.d.ts +63 -0
- package/dist/operations/proof/explain.d.ts.map +1 -1
- package/dist/operations/proof/explain.js +162 -0
- package/dist/operations/semantic-advisor/analyze-prose.d.ts +9 -1
- package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/analyze-prose.js +21 -0
- package/dist/operations/semantic-advisor/case-preview.d.ts +24 -0
- package/dist/operations/semantic-advisor/case-preview.d.ts.map +1 -0
- package/dist/operations/semantic-advisor/case-preview.js +216 -0
- package/dist/operations/semantic-advisor/shared.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/shared.js +3 -0
- package/dist/operations/semantic-advisor/types.d.ts +23 -0
- package/dist/operations/semantic-advisor/types.d.ts.map +1 -1
- package/dist/plugins/approved-source-analyzers.generated.d.ts +11 -8
- package/dist/plugins/approved-source-analyzers.generated.d.ts.map +1 -1
- package/dist/plugins/approved-source-analyzers.generated.js +11 -8
- package/dist/plugins/compose-search-hints.d.ts +29 -0
- package/dist/plugins/compose-search-hints.d.ts.map +1 -0
- package/dist/plugins/compose-search-hints.js +94 -0
- package/dist/plugins/external-allowlist.d.ts +7 -0
- package/dist/plugins/external-allowlist.d.ts.map +1 -1
- package/dist/plugins/external-allowlist.js +11 -0
- package/dist/plugins/registry.d.ts +8 -1
- package/dist/plugins/registry.d.ts.map +1 -1
- package/dist/plugins/registry.js +22 -3
- package/dist/plugins/source-classification.d.ts +2 -2
- package/dist/plugins/source-classification.d.ts.map +1 -1
- package/dist/plugins/source-classification.js +25 -1
- package/dist/prolog/codec.d.ts.map +1 -1
- package/dist/prolog/codec.js +10 -20
- package/dist/public/impact/coverage-depth-quality.d.ts.map +1 -1
- package/dist/public/impact/coverage-depth-quality.js +32 -16
- package/dist/public/impact/full-kb-quality.d.ts +6 -0
- package/dist/public/impact/full-kb-quality.d.ts.map +1 -1
- package/dist/public/impact/full-kb-quality.js +8 -3
- package/dist/public/impact/requirement-quality.d.ts.map +1 -1
- package/dist/public/impact/requirement-quality.js +56 -29
- package/dist/public/operations/catalog.d.ts +44 -4
- package/dist/public/operations/catalog.d.ts.map +1 -1
- package/dist/public/operations/check-executor.d.ts +6 -0
- package/dist/public/operations/check-executor.d.ts.map +1 -1
- package/dist/public/operations/check-executor.js +34 -2
- package/dist/public/operations/discovery-executors.d.ts +5 -1
- package/dist/public/operations/discovery-executors.d.ts.map +1 -1
- package/dist/public/operations/discovery-executors.js +65 -4
- package/dist/public/operations/evidence-floor.d.ts +8 -1
- package/dist/public/operations/evidence-floor.d.ts.map +1 -1
- package/dist/public/operations/evidence-floor.js +3 -4
- package/dist/public/operations/migration-plan.d.ts.map +1 -1
- package/dist/public/operations/migration-plan.js +41 -10
- package/dist/public/operations/node-ports.d.ts.map +1 -1
- package/dist/public/operations/node-ports.js +3 -1
- package/dist/public/operations/repair-plan.d.ts +46 -0
- package/dist/public/operations/repair-plan.d.ts.map +1 -1
- package/dist/public/operations/repair-plan.js +110 -1
- package/dist/public/operations/schema6-check-actions.js +1 -1
- package/dist/public/operations/source-analysis-cache.d.ts +22 -0
- package/dist/public/operations/source-analysis-cache.d.ts.map +1 -0
- package/dist/public/operations/source-analysis-cache.js +157 -0
- package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
- package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
- package/dist/public/operations/specs/check-rules.generated.js +2 -1
- package/dist/public/operations/specs/check.d.ts +1 -1
- package/dist/public/operations/specs/discovery.d.ts +7 -2
- package/dist/public/operations/specs/discovery.d.ts.map +1 -1
- package/dist/public/operations/specs/discovery.js +7 -2
- package/dist/public/operations/specs/mutation-schemas.d.ts +36 -1
- package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
- package/dist/public/operations/specs/mutation-schemas.js +30 -0
- package/dist/public/operations/specs/upsert.d.ts +36 -1
- package/dist/public/operations/specs/upsert.d.ts.map +1 -1
- package/dist/public/operations/symbol-granularity-check.d.ts +3 -1
- package/dist/public/operations/symbol-granularity-check.d.ts.map +1 -1
- package/dist/public/operations/symbol-granularity-check.js +21 -7
- package/dist/public/proof-protocol.d.ts +6 -1
- package/dist/public/proof-protocol.d.ts.map +1 -1
- package/dist/public/proof-protocol.js +12 -3
- package/dist/public/proof-sources.d.ts +2 -0
- package/dist/public/proof-sources.d.ts.map +1 -1
- package/dist/public/proof-sources.js +32 -6
- package/dist/public/schemas/entity.d.ts.map +1 -1
- package/dist/public/schemas/entity.js +59 -0
- package/dist/public/skills/kibi-bootstrap/SKILL.md +2 -2
- package/dist/public/skills/kibi-commit-review/SKILL.md +6 -2
- package/dist/public/skills/kibi-decisions/SKILL.md +7 -2
- package/dist/public/skills/kibi-decisions/resources/signoff-views.md +3 -1
- package/dist/public/skills/kibi-usage/SKILL.md +50 -3
- package/dist/public/skills/kibi-usage/resources/fact-lanes.md +34 -0
- package/dist/public/skills/kibi-usage/resources/proof.md +13 -5
- package/dist/public/skills/kibi-usage/resources/workflows.md +10 -0
- package/dist/relationships/shards.d.ts +2 -0
- package/dist/relationships/shards.d.ts.map +1 -1
- package/dist/relationships/shards.js +25 -1
- package/dist/schemas/entity.schema.json +98 -1
- package/dist/search-answer.d.ts +3 -2
- package/dist/search-answer.d.ts.map +1 -1
- package/dist/search-answer.js +57 -4
- package/dist/search-hints.d.ts +58 -0
- package/dist/search-hints.d.ts.map +1 -0
- package/dist/search-hints.js +187 -0
- package/dist/search-ranking.d.ts +7 -0
- package/dist/search-ranking.d.ts.map +1 -1
- package/dist/search-ranking.js +54 -56
- package/dist/search-token-cache.d.ts +30 -0
- package/dist/search-token-cache.d.ts.map +1 -0
- package/dist/search-token-cache.js +86 -0
- package/dist/traceability/impact-knowledge.d.ts.map +1 -1
- package/dist/traceability/impact-knowledge.js +2 -0
- package/dist/traceability/temp-kb.d.ts.map +1 -1
- package/dist/traceability/temp-kb.js +11 -1
- package/dist/types/entities.d.ts +12 -0
- package/dist/types/entities.d.ts.map +1 -1
- package/dist/usage-telemetry.d.ts +20 -0
- package/dist/usage-telemetry.d.ts.map +1 -0
- package/dist/usage-telemetry.js +93 -0
- package/dist/utils/branch-resolver.d.ts.map +1 -1
- package/dist/utils/branch-resolver.js +1 -0
- package/dist/utils/rule-registry.generated.d.ts +5 -0
- package/dist/utils/rule-registry.generated.d.ts.map +1 -1
- package/dist/utils/rule-registry.generated.js +6 -0
- package/package.json +5 -4
- package/schema/entities.pl +12 -0
- package/src/public/impact/coverage-depth-quality.ts +59 -21
- package/src/public/impact/full-kb-quality.ts +15 -1
- package/src/public/impact/requirement-quality.ts +95 -38
- package/src/public/operations/check-executor.ts +41 -1
- package/src/public/operations/discovery-executors.ts +92 -4
- package/src/public/operations/evidence-floor.ts +15 -3
- package/src/public/operations/migration-plan.ts +41 -9
- package/src/public/operations/node-ports.ts +3 -1
- package/src/public/operations/repair-plan.ts +152 -1
- package/src/public/operations/schema6-check-actions.ts +1 -1
- package/src/public/operations/source-analysis-cache.ts +196 -0
- package/src/public/operations/specs/check-rules.generated.ts +2 -1
- package/src/public/operations/specs/discovery.ts +8 -2
- package/src/public/operations/specs/mutation-schemas.ts +34 -0
- package/src/public/operations/symbol-granularity-check.ts +25 -5
- package/src/public/proof-protocol-types.d.ts +1 -1
- package/src/public/proof-protocol.ts +18 -4
- package/src/public/proof-sources.ts +37 -6
- package/src/public/schemas/entity.ts +65 -0
- package/src/public/skills/kibi-bootstrap/SKILL.md +2 -2
- package/src/public/skills/kibi-commit-review/SKILL.md +6 -2
- package/src/public/skills/kibi-decisions/SKILL.md +7 -2
- package/src/public/skills/kibi-decisions/resources/signoff-views.md +3 -1
- package/src/public/skills/kibi-usage/SKILL.md +50 -3
- package/src/public/skills/kibi-usage/resources/fact-lanes.md +34 -0
- package/src/public/skills/kibi-usage/resources/proof.md +13 -5
- package/src/public/skills/kibi-usage/resources/workflows.md +10 -0
- package/src/schemas/entity.schema.json +98 -1
|
@@ -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.
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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)
|
|
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
|
|
|
@@ -30,6 +30,8 @@ export declare function computeShardPath(kbRoot: string, entityId: string): stri
|
|
|
30
30
|
* Throws on parse errors.
|
|
31
31
|
*/
|
|
32
32
|
export declare function readShard(shardPath: string): RelationshipRecord[];
|
|
33
|
+
/** How many parsed shards the reuse memo holds; for tests of its bound. */
|
|
34
|
+
export declare function parsedShardMemoSize(): number;
|
|
33
35
|
/**
|
|
34
36
|
* Parses relationship shard text read from `shardPath`.
|
|
35
37
|
* Returns an empty array for blank text. Throws on parse errors.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shards.d.ts","sourceRoot":"","sources":["../../src/relationships/shards.ts"],"names":[],"mappings":"AAwBA;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGzE;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,EAAE,
|
|
1
|
+
{"version":3,"file":"shards.d.ts","sourceRoot":"","sources":["../../src/relationships/shards.ts"],"names":[],"mappings":"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"}
|
|
@@ -51,7 +51,31 @@ export function readShard(shardPath) {
|
|
|
51
51
|
if (!fs.existsSync(shardPath)) {
|
|
52
52
|
return [];
|
|
53
53
|
}
|
|
54
|
-
|
|
54
|
+
const content = fs.readFileSync(shardPath, "utf8");
|
|
55
|
+
const parsed = parsedShards.get(content);
|
|
56
|
+
// rationale: parsing is a pure function of the text and callers get copies
|
|
57
|
+
// either way, so skipping the memo changes only the time a read takes.
|
|
58
|
+
// Stryker disable next-line ConditionalExpression
|
|
59
|
+
if (parsed !== undefined)
|
|
60
|
+
return parsed.map((record) => ({ ...record }));
|
|
61
|
+
const records = parseShardText(content, shardPath);
|
|
62
|
+
if (parsedShards.size >= PARSED_SHARD_LIMIT)
|
|
63
|
+
parsedShards.clear();
|
|
64
|
+
parsedShards.set(content, records.map((record) => ({ ...record })));
|
|
65
|
+
return records;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Parsed shards by their text. One check reads every shard for several rules
|
|
69
|
+
* (relationship parity, entity context); a shard's records are a pure
|
|
70
|
+
* function of its text, so an unchanged shard is parsed once per process.
|
|
71
|
+
* Callers get their own record copies.
|
|
72
|
+
*/
|
|
73
|
+
const PARSED_SHARD_LIMIT = 1024;
|
|
74
|
+
const parsedShards = new Map();
|
|
75
|
+
/** How many parsed shards the reuse memo holds; for tests of its bound. */
|
|
76
|
+
// implements REQ-005
|
|
77
|
+
export function parsedShardMemoSize() {
|
|
78
|
+
return parsedShards.size;
|
|
55
79
|
}
|
|
56
80
|
/**
|
|
57
81
|
* Parses relationship shard text read from `shardPath`.
|
|
@@ -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"
|
package/dist/search-answer.d.ts
CHANGED
|
@@ -218,8 +218,9 @@ export declare function buildSearchAnswer(prolog: Pick<PrologPort, "query">, mat
|
|
|
218
218
|
/**
|
|
219
219
|
* Hold the whole answer under `maxBytes`, marking it truncated when anything
|
|
220
220
|
* is cut. In order: long titles, excerpts and details are clipped; ADR
|
|
221
|
-
* excerpts are dropped, last rationale entry first;
|
|
222
|
-
*
|
|
221
|
+
* excerpts are dropped, last rationale entry first; each governing
|
|
222
|
+
* requirement keeps only its first scenario and test, last requirement first;
|
|
223
|
+
* the least relevant governing requirements are dropped;
|
|
223
224
|
* list items are dropped (notes and side lists before the remaining
|
|
224
225
|
* requirement's own lists, its verdict witnesses last); then the remaining
|
|
225
226
|
* requirement's title and `via` are clipped. A verdict keeps its status when
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-answer.d.ts","sourceRoot":"","sources":["../src/search-answer.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"search-answer.d.ts","sourceRoot":"","sources":["../src/search-answer.ts"],"names":[],"mappings":"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"}
|
package/dist/search-answer.js
CHANGED
|
@@ -20,6 +20,7 @@ const ANSWER_RELATIONSHIPS = [
|
|
|
20
20
|
"specified_by",
|
|
21
21
|
"verified_by",
|
|
22
22
|
"validates",
|
|
23
|
+
"assumes",
|
|
23
24
|
"implements",
|
|
24
25
|
"constrains",
|
|
25
26
|
"requires_property",
|
|
@@ -206,7 +207,7 @@ function factDetail(fact, schema) {
|
|
|
206
207
|
}
|
|
207
208
|
function edgesGoal(ids) {
|
|
208
209
|
const idList = ids.map((id) => `'${escapeAtom(id)}'`).join(",");
|
|
209
|
-
return `
|
|
210
|
+
return `kb_relationship_edges([${ANSWER_RELATIONSHIPS.join(",")}], [${idList}], Edges)`;
|
|
210
211
|
}
|
|
211
212
|
/**
|
|
212
213
|
* For each predicate fact among `ids`, the argument names and key arguments
|
|
@@ -643,6 +644,10 @@ export async function buildSearchAnswer(prolog, matches, options = {}) {
|
|
|
643
644
|
// A matched test may verify a scenario rather than a requirement; its
|
|
644
645
|
// targets are resolved to their governing requirements after the loop.
|
|
645
646
|
const testTargets = [];
|
|
647
|
+
// A matched fact that no requirement grounds may be the assumption of a
|
|
648
|
+
// requirement's scenario, such as its failure side; it is resolved through
|
|
649
|
+
// that scenario after the loop.
|
|
650
|
+
const assumedFacts = [];
|
|
646
651
|
for (const [index, match] of seeds.entries()) {
|
|
647
652
|
const id = text(match.entity.id);
|
|
648
653
|
const entity = graph.row(id) ?? match.entity;
|
|
@@ -674,6 +679,19 @@ export async function buildSearchAnswer(prolog, matches, options = {}) {
|
|
|
674
679
|
testTargets.push({ id, score: match.score, targets: owners });
|
|
675
680
|
continue;
|
|
676
681
|
}
|
|
682
|
+
if (type === "fact" && owners.length === 0) {
|
|
683
|
+
const scenarios = seedEdges
|
|
684
|
+
.filter((edge) => edge.rel === "assumes" && edge.to === id)
|
|
685
|
+
.map((edge) => edge.from);
|
|
686
|
+
if (scenarios.length > 0) {
|
|
687
|
+
assumedFacts.push({
|
|
688
|
+
id,
|
|
689
|
+
score: match.score,
|
|
690
|
+
scenarios: unique(scenarios),
|
|
691
|
+
});
|
|
692
|
+
continue;
|
|
693
|
+
}
|
|
694
|
+
}
|
|
677
695
|
if (owners.length === 0 && ["fact", "scenario", "symbol"].includes(type)) {
|
|
678
696
|
// A fact's claim and ask are filled in once its schema is known.
|
|
679
697
|
if (ungoverned.length < limits.ungoverned)
|
|
@@ -688,7 +706,10 @@ export async function buildSearchAnswer(prolog, matches, options = {}) {
|
|
|
688
706
|
const byScore = () => [...candidates.entries()]
|
|
689
707
|
.sort(([, left], [, right]) => right.score - left.score)
|
|
690
708
|
.map(([id]) => id);
|
|
691
|
-
const targetIds = unique(
|
|
709
|
+
const targetIds = unique([
|
|
710
|
+
...testTargets.flatMap((test) => test.targets),
|
|
711
|
+
...assumedFacts.flatMap((fact) => fact.scenarios),
|
|
712
|
+
]);
|
|
692
713
|
// Test targets and the candidates found so far share one round trip.
|
|
693
714
|
await graph.fetch({
|
|
694
715
|
edges: [...targetIds, ...byScore()],
|
|
@@ -720,6 +741,22 @@ export async function buildSearchAnswer(prolog, matches, options = {}) {
|
|
|
720
741
|
propose(owner, test.score * 0.85, `test ${test.id} via ${target}`);
|
|
721
742
|
}
|
|
722
743
|
}
|
|
744
|
+
for (const fact of assumedFacts) {
|
|
745
|
+
const owners = fact.scenarios.flatMap((scenario) => targetEdges
|
|
746
|
+
.filter((edge) => edge.rel === "specified_by" && edge.to === scenario)
|
|
747
|
+
.map((edge) => ({ owner: edge.from, scenario })));
|
|
748
|
+
if (owners.length === 0) {
|
|
749
|
+
const row = graph.row(fact.id);
|
|
750
|
+
const rank = seedIds.indexOf(fact.id) + 1;
|
|
751
|
+
if (row !== null && ungoverned.length < limits.ungoverned)
|
|
752
|
+
ungoverned.push({ ...brief(row), type: "fact", rank });
|
|
753
|
+
else if (row !== null)
|
|
754
|
+
truncated = true;
|
|
755
|
+
continue;
|
|
756
|
+
}
|
|
757
|
+
for (const { owner, scenario } of owners)
|
|
758
|
+
propose(owner, fact.score * 0.85, `fact ${fact.id} via ${scenario}`);
|
|
759
|
+
}
|
|
723
760
|
const supersededBy = new Map();
|
|
724
761
|
for (const edge of seedEdges)
|
|
725
762
|
if (edge.rel === "supersedes")
|
|
@@ -1035,8 +1072,9 @@ const REQUIREMENT_TRIM_ORDER = [
|
|
|
1035
1072
|
/**
|
|
1036
1073
|
* Hold the whole answer under `maxBytes`, marking it truncated when anything
|
|
1037
1074
|
* is cut. In order: long titles, excerpts and details are clipped; ADR
|
|
1038
|
-
* excerpts are dropped, last rationale entry first;
|
|
1039
|
-
*
|
|
1075
|
+
* excerpts are dropped, last rationale entry first; each governing
|
|
1076
|
+
* requirement keeps only its first scenario and test, last requirement first;
|
|
1077
|
+
* the least relevant governing requirements are dropped;
|
|
1040
1078
|
* list items are dropped (notes and side lists before the remaining
|
|
1041
1079
|
* requirement's own lists, its verdict witnesses last); then the remaining
|
|
1042
1080
|
* requirement's title and `via` are clipped. A verdict keeps its status when
|
|
@@ -1084,6 +1122,21 @@ export function fitSearchAnswer(answer, maxBytes = SEARCH_ANSWER_LIMITS.maxBytes
|
|
|
1084
1122
|
rationale[index] = withoutExcerpt(rationale[index]);
|
|
1085
1123
|
current = { ...current, rationale };
|
|
1086
1124
|
}
|
|
1125
|
+
// A requirement's second scenario or test matters less than another
|
|
1126
|
+
// governing requirement: keep one of each, last requirement first, before
|
|
1127
|
+
// dropping a requirement.
|
|
1128
|
+
for (let index = current.governing.length - 1; index >= 0 && over(); index -= 1) {
|
|
1129
|
+
const governing = [...current.governing];
|
|
1130
|
+
const req = governing[index];
|
|
1131
|
+
if (req.scenarios.length <= 1 && req.tests.length <= 1)
|
|
1132
|
+
continue;
|
|
1133
|
+
governing[index] = {
|
|
1134
|
+
...req,
|
|
1135
|
+
scenarios: req.scenarios.slice(0, 1),
|
|
1136
|
+
tests: req.tests.slice(0, 1),
|
|
1137
|
+
};
|
|
1138
|
+
current = { ...current, governing };
|
|
1139
|
+
}
|
|
1087
1140
|
while (over() && current.governing.length > 1)
|
|
1088
1141
|
current = { ...current, governing: current.governing.slice(0, -1) };
|
|
1089
1142
|
while (over()) {
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { PluginProviderStamp, SearchHintsEntity, SearchHintsV1 } from "kibi-plugin-sdk";
|
|
2
|
+
import { type IntentSearchAnalysis, type MarkdownBodyCache } from "./intent-search.js";
|
|
3
|
+
import { type SearchHintsDiagnostic } from "./plugins/compose-search-hints.js";
|
|
4
|
+
import type { CapabilityModeResolution } from "./plugins/registry.js";
|
|
5
|
+
import type { PrologPort } from "./public/operations/runtime-types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Below this top score a lexical answer is weak enough to show hints. On
|
|
8
|
+
* Kibi's own KB, 17 of 18 reworded questions the ranker got wrong scored
|
|
9
|
+
* below it, against 6 of 30 gold questions it got right. Host-owned, so no
|
|
10
|
+
* provider can move it.
|
|
11
|
+
*/
|
|
12
|
+
export declare const SEARCH_HINT_WEAK_SCORE = 0.44;
|
|
13
|
+
/** Requirements shown as hints. */
|
|
14
|
+
export declare const SEARCH_HINT_LIMIT = 10;
|
|
15
|
+
export type SearchHintsTrigger = "abstained" | "weak";
|
|
16
|
+
export type SearchHintItem = Readonly<{
|
|
17
|
+
id: string;
|
|
18
|
+
title: string;
|
|
19
|
+
score: number;
|
|
20
|
+
/** The entity the provider matched, when the hint is its requirement. */
|
|
21
|
+
via?: string;
|
|
22
|
+
}>;
|
|
23
|
+
export type SearchHintsAnalysis = Readonly<{
|
|
24
|
+
trigger: SearchHintsTrigger;
|
|
25
|
+
provider: PluginProviderStamp | null;
|
|
26
|
+
items: readonly SearchHintItem[];
|
|
27
|
+
shadow?: readonly {
|
|
28
|
+
readonly provider: PluginProviderStamp;
|
|
29
|
+
readonly items: readonly {
|
|
30
|
+
readonly id: string;
|
|
31
|
+
readonly score: number;
|
|
32
|
+
}[];
|
|
33
|
+
}[];
|
|
34
|
+
diagnostics?: readonly SearchHintsDiagnostic[];
|
|
35
|
+
}>;
|
|
36
|
+
/** Why a lexical answer needs hints, or null when it is strong enough. */
|
|
37
|
+
export declare function searchHintsTrigger(analysis: IntentSearchAnalysis): SearchHintsTrigger | null;
|
|
38
|
+
/** The current entities a provider may hint at, as the search loaded them. */
|
|
39
|
+
export declare function searchHintsEntities(entities: readonly Record<string, unknown>[], bodies: MarkdownBodyCache, workspaceRoot: string): SearchHintsEntity[];
|
|
40
|
+
/**
|
|
41
|
+
* Ask the configured kibi.search-hints.v1 provider which current entities a
|
|
42
|
+
* weakly answered question is probably about. Returns undefined when the
|
|
43
|
+
* answer is strong or no provider is configured. Hints never change the
|
|
44
|
+
* ranked results, the governing answer or abstention.
|
|
45
|
+
*/
|
|
46
|
+
export declare function buildSearchHints(options: Readonly<{
|
|
47
|
+
query: string;
|
|
48
|
+
analysis: IntentSearchAnalysis;
|
|
49
|
+
entities: readonly Record<string, unknown>[];
|
|
50
|
+
bodies: MarkdownBodyCache;
|
|
51
|
+
governingIds: readonly string[];
|
|
52
|
+
resolution: CapabilityModeResolution<SearchHintsV1>;
|
|
53
|
+
prolog: Pick<PrologPort, "query">;
|
|
54
|
+
workspaceRoot: string;
|
|
55
|
+
}>): Promise<SearchHintsAnalysis | undefined>;
|
|
56
|
+
/** The sentence a search answer's text adds when hints are shown. */
|
|
57
|
+
export declare function searchHintsNote(hints: SearchHintsAnalysis | undefined): string;
|
|
58
|
+
//# sourceMappingURL=search-hints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-hints.d.ts","sourceRoot":"","sources":["../src/search-hints.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,mBAAmB,EACnB,iBAAiB,EACjB,aAAa,EACd,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EAGvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,KAAK,qBAAqB,EAE3B,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AAEtE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AAIvE;;;;;GAKG;AAEH,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAC3C,mCAAmC;AAEnC,eAAO,MAAM,iBAAiB,KAAK,CAAC;AAYpC,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,MAAM,CAAC;AAGtD,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC,CAAC;AAGH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,OAAO,EAAE,kBAAkB,CAAC;IAC5B,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACrC,KAAK,EAAE,SAAS,cAAc,EAAE,CAAC;IACjC,MAAM,CAAC,EAAE,SAAS;QAChB,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;QACvC,QAAQ,CAAC,KAAK,EAAE,SAAS;YAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;KAC5E,EAAE,CAAC;IACJ,WAAW,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;CAChD,CAAC,CAAC;AAEH,0EAA0E;AAE1E,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,oBAAoB,GAC7B,kBAAkB,GAAG,IAAI,CAG3B;AAwCD,8EAA8E;AAE9E,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC5C,MAAM,EAAE,iBAAiB,EACzB,aAAa,EAAE,MAAM,GACpB,iBAAiB,EAAE,CAiBrB;AAuDD;;;;;GAKG;AAEH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,QAAQ,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,QAAQ,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAC7C,MAAM,EAAE,iBAAiB,CAAC;IAC1B,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,UAAU,EAAE,wBAAwB,CAAC,aAAa,CAAC,CAAC;IACpD,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAClC,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC,GACD,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAgD1C;AAED,qEAAqE;AAErE,wBAAgB,eAAe,CAC7B,KAAK,EAAE,mBAAmB,GAAG,SAAS,GACrC,MAAM,CAOR"}
|