kibi-cursor 2.2.0 → 2.3.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 (43) hide show
  1. package/.cursor-plugin/plugin.json +1 -1
  2. package/CHANGELOG.md +86 -0
  3. package/README.md +3 -2
  4. package/agent-plugin/plugin.json +1 -1
  5. package/agent-plugin/skills/kibi-bootstrap/SKILL.md +6 -1
  6. package/agent-plugin/skills/kibi-bootstrap/resources/bootstrap.md +6 -0
  7. package/agent-plugin/skills/kibi-usage/SKILL.md +68 -18
  8. package/agent-plugin/skills/kibi-usage/resources/fact-lanes.md +5 -5
  9. package/agent-plugin/skills/kibi-usage/resources/kb-improvement.md +1 -1
  10. package/agent-plugin/skills/kibi-usage/resources/logic-ir.md +2 -2
  11. package/agent-plugin/skills/kibi-usage/resources/operation-access.md +25 -1
  12. package/agent-plugin/skills/kibi-usage/resources/ui-requirements.md +4 -4
  13. package/agent-plugin/skills/kibi-usage/resources/workflows.md +42 -25
  14. package/bin/launch-kibi-mcp.mjs +4 -1
  15. package/dist/.cursor-plugin/plugin.json +1 -1
  16. package/dist/bin/launch-kibi-mcp.mjs +4 -1
  17. package/dist/guidance.d.ts +8 -0
  18. package/dist/guidance.js +13 -0
  19. package/dist/hook-runner.d.ts +2 -0
  20. package/dist/hook-runner.js +69 -2
  21. package/dist/skills/.canon-hash.json +9 -9
  22. package/dist/skills/kibi-bootstrap/SKILL.md +6 -1
  23. package/dist/skills/kibi-bootstrap/resources/bootstrap.md +6 -0
  24. package/dist/skills/kibi-usage/SKILL.md +68 -18
  25. package/dist/skills/kibi-usage/resources/fact-lanes.md +5 -5
  26. package/dist/skills/kibi-usage/resources/kb-improvement.md +1 -1
  27. package/dist/skills/kibi-usage/resources/logic-ir.md +2 -2
  28. package/dist/skills/kibi-usage/resources/operation-access.md +25 -1
  29. package/dist/skills/kibi-usage/resources/ui-requirements.md +4 -4
  30. package/dist/skills/kibi-usage/resources/workflows.md +42 -25
  31. package/dist/source-linked-requirements.d.ts +13 -3
  32. package/dist/source-linked-requirements.js +14 -15
  33. package/package.json +2 -2
  34. package/skills/.canon-hash.json +9 -9
  35. package/skills/kibi-bootstrap/SKILL.md +6 -1
  36. package/skills/kibi-bootstrap/resources/bootstrap.md +6 -0
  37. package/skills/kibi-usage/SKILL.md +68 -18
  38. package/skills/kibi-usage/resources/fact-lanes.md +5 -5
  39. package/skills/kibi-usage/resources/kb-improvement.md +1 -1
  40. package/skills/kibi-usage/resources/logic-ir.md +2 -2
  41. package/skills/kibi-usage/resources/operation-access.md +25 -1
  42. package/skills/kibi-usage/resources/ui-requirements.md +4 -4
  43. package/skills/kibi-usage/resources/workflows.md +42 -25
@@ -4,12 +4,12 @@ Kibi stores human prose as readable requirement text, but verifiable meaning bel
4
4
 
5
5
  ## Two-pass extraction
6
6
 
7
- 1. Run `kb_semantic_advisor` over the complete text. Supply explicit `clauses` when sentence splitting could hide a condition, exception, definition, descriptive assertion, threshold, quantity, or temporal qualifier.
7
+ 1. Run `kb_model` with `mode: "analyze"` over the complete text. Supply explicit `clauses` when sentence splitting could hide a condition, exception, definition, descriptive assertion, threshold, quantity, or temporal qualifier.
8
8
  2. Audit the returned `propositions` against the original UTF-8 text. Every assertive span must be `modeled`, `ambiguous`, `ontology_gap`, or `missing`; rationale, examples, and subjective commentary are `nonlogical` and remain readable prose.
9
9
  3. For each assertive proposition, submit up to three typed `interpretations` when alternatives are plausible. Kibi compares canonical semantic keys; materially different valid interpretations remain unresolved regardless of confidence.
10
10
  4. Apply only a validated plan, then read back the requirement, rule schema, rule fact, and all relationship targets. Run `rule-safety`, `rule-verifiability`, `semantic-completeness`, `logic-coverage`, and `domain-contradictions` before the final unfiltered check.
11
11
 
12
- When a project-local schema names several ordered arguments, those arguments are facets of one relation, not separate propositions. Preserve the advisor claim key for the complete relation and do not manufacture clauses for each argument. Supporting `predicate_schema` facts carry the declared signature only; the ground predicate fact carries the claim provenance. Apply the exact `kb_suggest_predicates`/`kb_model_requirement` plan, reducing a rejected schema payload through `kb_validate_upsert` rather than silently downgrading a fitting declared relation to an observation.
12
+ When a project-local schema names several ordered arguments, those arguments are facets of one relation, not separate propositions. Preserve the advisor claim key for the complete relation and do not manufacture clauses for each argument. Supporting `predicate_schema` facts carry the declared signature only; the ground predicate fact carries the claim provenance. Apply the exact `kb_model` predicates/requirement plan, reducing a rejected schema payload through `kb_upsert` with `dryRun: true` rather than silently downgrading a fitting declared relation to an observation.
13
13
 
14
14
  ## Logic IR shape
15
15
 
@@ -4,11 +4,12 @@ Generated from the public `OperationSpec` catalog. CLI JSON and MCP structured
4
4
  content use the same `KibiResult` envelope (protocol 1); result data is versioned
5
5
  per operation. Effects are authoritative for mutability and adapter annotations.
6
6
 
7
- | MCP tool name | CLI route | Input mode | Mutability | Requires Prolog | Effects | Interface | Result version | Destructive | Retry safety | Open-world | Output schema |
7
+ | Operation | CLI route | Input mode | Mutability | Requires Prolog | Effects | Interface | Result version | Destructive | Retry safety | Open-world | Output schema |
8
8
  |---|---|---|---|---|---|---|---|---|---|---|---|
9
9
  | `kb_skills_list` | `skills-list` | --input JSON | read | no | local-read | peer; capability-selected | kibi.kb_skills_list.v1 | no | safe | no | yes |
10
10
  | `kb_skills_load` | `skills-load` | --input JSON | read | no | local-read | peer; capability-selected | kibi.kb_skills_load.v1 | no | safe | no | yes |
11
11
  | `kb_skills_read` | `skills-read` | --input JSON | read | no | local-read | peer; capability-selected | kibi.kb_skills_read.v1 | no | safe | no | yes |
12
+ | `kb_skills` | `skill` | --input JSON | read | no | local-read | peer; capability-selected | kibi.kb_skills.v1 | no | safe | no | yes |
12
13
  | `kb_query` | `query` | --input JSON or flags | read | yes | kb-read | peer; capability-selected | kibi.kb_query.v1 | no | safe | no | yes |
13
14
  | `kb_search` | `search` | --input JSON or flags | read | yes | kb-read | peer; capability-selected | kibi.kb_search.v1 | no | safe | no | yes |
14
15
  | `kb_status` | `status` | --input JSON or flags | read | no | kb-read, workspace-read | peer; capability-selected | kibi.kb_status.v1 | no | safe | no | yes |
@@ -18,6 +19,7 @@ per operation. Effects are authoritative for mutability and adapter annotations.
18
19
  | `kb_semantic_advisor` | `semantic-advisor` | --input JSON | read | no | local-read | peer; capability-selected | kibi.kb_semantic_advisor.v1 | no | safe | no | yes |
19
20
  | `kb_model_requirement` | `model-requirement` | --input JSON | read | yes | kb-read | peer; capability-selected | kibi.kb_model_requirement.v1 | no | safe | no | yes |
20
21
  | `kb_suggest_predicates` | `suggest-predicates` | --input JSON | read | yes | kb-read | peer; capability-selected | kibi.kb_suggest_predicates.v1 | no | safe | no | yes |
22
+ | `kb_model` | `model` | --input JSON | read | yes | kb-read | peer; capability-selected | kibi.kb_model.v1 | no | safe | no | yes |
21
23
  | `kb_plan_bootstrap` | `plan-bootstrap` | --input JSON | read | no | workspace-read | peer; capability-selected | kibi.kb_plan_bootstrap.v1 | no | safe | no | yes |
22
24
  | `kb_validate_upsert` | `validate-upsert` | --input JSON | read | yes | kb-read | peer; capability-selected | kibi.kb_validate_upsert.v1 | no | safe | no | yes |
23
25
  | `kb_upsert` | `upsert` | --input JSON | write | yes | kb-write, workspace-write | peer; capability-selected | kibi.kb_upsert.v1 | yes | unsafe | no | yes |
@@ -29,6 +31,28 @@ per operation. Effects are authoritative for mutability and adapter annotations.
29
31
  | `kb_apply_plan` | `apply-plan` | --input JSON | write | yes | kb-read, kb-write, workspace-read, workspace-write | peer; capability-selected | kibi.kb_apply_plan.v1 | yes | unsafe | no | yes |
30
32
  | `kb_ingest_proof` | `ingest-proof` | --input JSON | write | yes | kb-read, kb-write, workspace-read | peer; capability-selected | kibi.kb_ingest_proof.v1 | yes | unsafe | no | yes |
31
33
 
34
+ ## MCP tools versus catalog operations
35
+
36
+ The MCP server registers 16 tools. Most carry their catalog operation name; the
37
+ operations below are reached through a consolidated MCP call instead, while the
38
+ CLI keeps their dedicated routes. Result payloads (for example
39
+ `recommended_tools`, `suggested_next_tool`, or repair-plan steps) still name
40
+ catalog operations, so translate them with this list.
41
+
42
+ - `kb_skills_list`: MCP `kb_skills` with `action: "list"`; CLI `kibi skills list` (`skills-list`)
43
+ - `kb_skills_load`: MCP `kb_skills` with `action: "load"`; CLI `kibi skills load` (`skills-load`)
44
+ - `kb_skills_read`: MCP `kb_skills` with `action: "read"`; CLI `kibi skills read` (`skills-read`)
45
+ - `kb_semantic_advisor`: MCP `kb_model` with `mode: "analyze"`; CLI `kibi semantic-advisor` (`semantic-advisor`)
46
+ - `kb_model_requirement`: MCP `kb_model` with `mode: "requirement"`; CLI `kibi model-requirement` (`model-requirement`)
47
+ - `kb_suggest_predicates`: MCP `kb_model` with `mode: "predicates"`; CLI `kibi suggest-predicates` (`suggest-predicates`)
48
+ - `kb_validate_upsert`: MCP `kb_upsert` with `dryRun: true`; CLI `kibi validate-upsert` (`validate-upsert`)
49
+ - `kb_sparql_remote`: MCP `kb_sparql_remote`, registered only when `KIBI_MCP_OPTIONAL_TOOLS` names it; CLI `kibi sparql-remote` (`sparql-remote`)
50
+
51
+ The consolidated tools also have their own CLI routes: `kibi skill` for
52
+ `kb_skills` and `kibi model` for `kb_model`. `kb_job_status` is likewise
53
+ opt-in through `KIBI_MCP_OPTIONAL_TOOLS`; without it, `kb_check` with
54
+ `async: true` runs synchronously.
55
+
32
56
  ## JSON execution recipe
33
57
 
34
58
  Use a trusted project-local, non-installing runner. Stdin contains one UTF-8 JSON
@@ -82,14 +82,14 @@ diagnostics (`symbol_semantic_review_needed`).
82
82
 
83
83
  ## Workflow
84
84
 
85
- 1. `kb_semantic_advisor` on the full description; audit or supply `clauses`.
86
- 2. Relational clauses: `kb_suggest_predicates`, apply the predicate plan and
85
+ 1. `kb_model` (`mode: "analyze"`) on the full description; audit or supply `clauses`.
86
+ 2. Relational clauses: `kb_model` (`mode: "predicates"`), apply the predicate plan and
87
87
  `requires_predicate`.
88
- 3. Scalar placement/alignment/order clauses: `kb_model_requirement`, apply the strict
88
+ 3. Scalar placement/alignment/order clauses: `kb_model` (`mode: "requirement"`), apply the strict
89
89
  subject/property plan and `constrains` / `requires_property`.
90
90
  4. Preserve `claim_key` / `claim_text`; merge every key into the requirement
91
91
  `logic_claims` manifest.
92
- 5. `kb_validate_upsert`, create endpoints first, then sequential `kb_upsert`.
92
+ 5. `kb_upsert` with `dryRun: true`, create endpoints first, then sequential `kb_upsert`.
93
93
  6. `kb_check` with `logic-coverage`, `predicate-verifiability`, `domain-contradictions`,
94
94
  then a final unfiltered `kb_check`.
95
95
 
@@ -35,21 +35,22 @@ edits dependency configuration.
35
35
 
36
36
  ## Choosing a discovery mode
37
37
 
38
- `kb_search` is not one behavior. It selects deterministic intent ranking when
39
- you pass `rankingMode: "intent-v1"`, `semanticFacets`, or `sourceLocations`,
40
- and legacy lexical ranking otherwise. Naming the tool is not enough; the inputs
41
- decide the path.
38
+ `kb_search` defaults to deterministic intent ranking (`rankingMode:
39
+ "intent-v1"`), so a natural-language question is a valid query. Pass
40
+ `rankingMode: "legacy"` for the older lexical ranking. The inputs, not the tool
41
+ name, decide how results are ranked.
42
42
 
43
43
  - **Exact identity** — you already know the ID. Use `kb_query`, not search.
44
44
  - **Literal token** — a symbol, file, or error string that appears verbatim.
45
- Use lexical `kb_search` and keep the query close to the literal text.
46
- - **Conceptual or behavioral** — "how does checkout handle a declined card".
47
- Use intent mode and ground it in what you actually know:
45
+ Keep the query close to the literal text; `rankingMode: "legacy"` ranks it
46
+ lexically.
47
+ - **Question or behavior** — "what governs how checkout handles a declined
48
+ card?". Ask it directly, and ground it with facets from what you actually
49
+ know:
48
50
 
49
51
  ```json
50
52
  {
51
- "query": "declined card during checkout",
52
- "rankingMode": "intent-v1",
53
+ "query": "what governs a declined card during checkout?",
53
54
  "semanticFacets": {
54
55
  "actors": ["shopper"],
55
56
  "actions": ["pay"],
@@ -66,7 +67,6 @@ decide the path.
66
67
  ```json
67
68
  {
68
69
  "query": "checkout total rounding",
69
- "rankingMode": "intent-v1",
70
70
  "sourceLocations": [{ "path": "src/checkout.ts", "symbol": "computeTotal" }]
71
71
  }
72
72
  ```
@@ -75,8 +75,25 @@ Supply facets only from the request, the code, or prior results. Inventing
75
75
  facets fabricates evidence and biases ranking. Intent mode abstains below
76
76
  `minScore` instead of returning weak matches; an abstention is an explicit
77
77
  no-answer, so widen the query or drop to lexical search rather than treating it
78
- as "nothing exists". There is no target percentage of intent-mode calls — a
79
- literal identifier lookup is still best served lexically.
78
+ as "nothing exists". A literal identifier lookup is still best served
79
+ lexically.
80
+
81
+ On the first page, intent mode also returns an answer layer in `data.answer`
82
+ (`kibi.search-answer.v1`; turn it off with `answer: false`):
83
+
84
+ - `governing` — current requirements matched by the query or linked to a
85
+ matched entity, each with `via` (how it was reached) and its linked `facts`,
86
+ `scenarios`, `tests`, and `adrs`.
87
+ - `rationale` — ADRs that explain the decisions.
88
+ - `notGoverning` — superseded or deprecated requirements, with `supersededBy`
89
+ when known. Never read these as current policy; superseded entities are also
90
+ demoted in the ranked results.
91
+ - `observations` — observation/meta facts, which are notes, not rules.
92
+ - `truncated` and `note` — the layer is size-bounded; an empty `governing`
93
+ list is not evidence that nothing governs the change.
94
+
95
+ The answer layer is graph traversal: discovery, not proof. Use `kb_check` and
96
+ `kb_coverage` for consistency and proof status.
80
97
 
81
98
  Results are summaries by default: identifying metadata, score, reasons, and a
82
99
  snippet. Read them to pick candidates, then `kb_query` those IDs for full
@@ -88,12 +105,12 @@ planning a behavior change; a search receipt is not comprehension.
88
105
 
89
106
  The canonical workflow for any KB operation follows this pattern:
90
107
 
91
- 1. **Discover**: `kb_search` with focused probes; pick the mode above
108
+ 1. **Discover**: `kb_search` with focused probes or a direct question; read `data.answer`, and pick the mode above
92
109
  2. **Confirm**: `kb_query` for exact IDs and state
93
110
  3. **Inspect**: `kb_status` when freshness matters
94
- 4. **Decompose**: `kb_semantic_advisor` on the complete normative prose; verify or supply every atomic clause
95
- 5. **Choose per-clause lanes**: strict facts for scalar claims; `kb_suggest_predicates` for approved ground ontology relations; `kb_model_requirement` with `kibi.logic.v1` for conditions, exceptions, modalities, quantifiers, cardinality, and bounded temporal rules; observation review for ambiguity, nonlogical prose, and ontology gaps
96
- 6. **Preflight**: `kb_validate_upsert` for every intended entity or relationship payload
111
+ 4. **Decompose**: `kb_model` (`mode: "analyze"`) on the complete normative prose; verify or supply every atomic clause
112
+ 5. **Choose per-clause lanes**: strict facts for scalar claims; `kb_model` `mode: "predicates"` for approved ground ontology relations; `kb_model` `mode: "requirement"` with `kibi.logic.v1` for conditions, exceptions, modalities, quantifiers, cardinality, and bounded temporal rules; observation review for ambiguity, nonlogical prose, and ontology gaps
113
+ 6. **Preflight**: `kb_upsert` with `dryRun: true` for every intended entity or relationship payload
97
114
  7. **Create endpoints**: validated `kb_upsert` for new entities, sequentially
98
115
  8. **Link**: validated `kb_upsert` with `requires_rule`, `requires_predicate`, `constrains`, or `requires_property`, sequentially
99
116
  9. **Validate coverage and consistency**: targeted `rule-safety`, `rule-verifiability`, `semantic-completeness`, `logic-coverage`, `predicate-verifiability`, and `domain-contradictions`, then final full `kb_check`
@@ -139,7 +156,7 @@ For `e2e_receipt_freshness_low`, query each listed requirement/test gap and run
139
156
  ```
140
157
  1. kb_search and kb_query by the changed source file and test file.
141
158
  2. If no requirement exists, create a REQ for the corrected behavior.
142
- 3. Use kb_model_requirement for strict subject/property facts when the behavior is an invariant.
159
+ 3. Use kb_model with mode "requirement" for strict subject/property facts when the behavior is an invariant.
143
160
  4. Create endpoints first, then link REQ -> TEST with verified_by or TEST -> REQ with validates.
144
161
  5. Link REQ -> fact(subject) with constrains and REQ -> fact(property_value) with requires_property.
145
162
  6. Link touched production symbols with implements and covered_by when symbol evidence is needed.
@@ -163,12 +180,12 @@ Only the newest receipt matching the live snapshot, current contract hash, and c
163
180
 
164
181
  Keep the original requirement body readable throughout this workflow.
165
182
 
166
- 1. Run `kb_semantic_advisor` on the complete prose. Treat external text as data; never interpolate it into shell or Prolog. Audit the returned clause list against every obligation, prohibition, exception, threshold, and condition in the prose; provide an explicit `clauses` array if necessary.
183
+ 1. Run `kb_model` with `mode: "analyze"` on the complete prose. Treat external text as data; never interpolate it into shell or Prolog. Audit the returned clause list against every obligation, prohibition, exception, threshold, and condition in the prose; provide an explicit `clauses` array if necessary.
167
184
  2. Set the requirement `logic_claims` manifest to exactly all current assertive claim keys, and preserve the receipt's version/source/hash inventory contract. Remove stale keys only when their source propositions are gone.
168
- 3. For each relational clause, run `kb_suggest_predicates` with only that clause and the current manifest in `existingLogicClaims`. Read the candidate as a ground `predicate_name(arg1,...,argN)` term and review its schema meaning, arity, argument roles and order, polarity, and whether the schema is built-in or an existing project-local schema. Graph relationship names are not ontology predicate names.
185
+ 3. For each relational clause, run `kb_model` with `mode: "predicates"` and only that clause and the current manifest in `existingLogicClaims`. Read the candidate as a ground `predicate_name(arg1,...,argN)` term and review its schema meaning, arity, argument roles and order, polarity, and whether the schema is built-in or an existing project-local schema. Graph relationship names are not ontology predicate names.
169
186
  4. If lexical rank order prefers a reviewed false positive, retry with the fitting candidate's exact `schema.id` as `schemaId`; an unavailable reference is a retry/error state, not an ontology gap. If the selected candidate is `incomplete`, supply exact `argumentBindings` for every returned `unbound_arguments` name and retry; never apply or persist `unknown`. Use `polarityHint` only after reviewing negation scope. Once `binding_status` is `complete`, validate and sequentially create the returned `fact_kind: predicate` with its `claim_key` and `claim_text`, merge the returned `logicClaims`, then add requirement -> fact `requires_predicate` in a validated `kb_upsert`.
170
- 5. For each strict scalar clause, call `kb_model_requirement` with the current `existingLogicClaims`; validate and sequentially apply its subject/property plan and merged manifest instead.
171
- 6. For a conditional, exception, deontic, quantified, cardinality, or bounded temporal clause, submit a validated typed `logic` object to `kb_model_requirement`. Apply its `rule_schema` and `rule` facts sequentially and link the requirement with `requires_rule`; rendered Prolog is for inspection only.
187
+ 5. For each strict scalar clause, call `kb_model` with `mode: "requirement"` and the current `existingLogicClaims`; validate and sequentially apply its subject/property plan and merged manifest instead.
188
+ 6. For a conditional, exception, deontic, quantified, cardinality, or bounded temporal clause, submit a validated typed `logic` object to `kb_model` with `mode: "requirement"`. Apply its `rule_schema` and `rule` facts sequentially and link the requirement with `requires_rule`; rendered Prolog is for inspection only.
172
189
  7. If wording is ambiguous, a candidate is only a lexical false positive, or no schema/IR interpretation fits, create the advised observation review artifact and apply its returned `relates_to` review anchor when present; report that claim key as unresolved. Use `review:ambiguity` for unresolved interpretation, `review:keyword-false-positive` for a vocabulary match that is not a domain assertion, and `review:ontology-gap` only for a true catalog gap. Define a new `predicate_schema` only when the task explicitly authorizes ontology extension and provides a stable signature.
173
190
  8. Read back the requirement, proposition ledger, and all facts. Confirm every manifest key occurs on exactly one intended ground fact/rule, no punctuation variant minted a second claim, and no two claim keys encode the same logical term. Exact query output may represent repeated relationship types as arrays, so inspect every target. Then run `kb_check` with `rule-safety`, `rule-verifiability`, `semantic-completeness`, `logic-coverage`, `predicate-verifiability`, and `domain-contradictions`. Finish with an unfiltered `kb_check`.
174
191
 
@@ -183,12 +200,12 @@ On resume after interruption, repeat `kb_query` for exact endpoints and apply on
183
200
  Optional per-project workflow for recording what the screen should look like. Non-UI projects skip this lane entirely.
184
201
 
185
202
  1. Create a prose `req` holding the full visual description; it is the searchable anchor agents discover before touching a UI file.
186
- 2. Run `kb_semantic_advisor` on the description; audit or supply `clauses`.
187
- 3. For relational layout clauses ("X must remain visually aligned with Y"), call `kb_suggest_predicates`, apply the returned `fact_kind: predicate` plan with `predicate_name: visual_layout_rule` and `requires_predicate`.
188
- 4. For scalar placement, alignment, and ordering clauses, call `kb_model_requirement` and apply strict `fact_kind: subject` / `fact_kind: property_value` facts linked with `constrains` / `requires_property`. Model header order as indexed property keys (`nav_order_1`, `nav_order_2`, ...) against one subject region.
203
+ 2. Run `kb_model` with `mode: "analyze"` on the description; audit or supply `clauses`.
204
+ 3. For relational layout clauses ("X must remain visually aligned with Y"), call `kb_model` with `mode: "predicates"`, apply the returned `fact_kind: predicate` plan with `predicate_name: visual_layout_rule` and `requires_predicate`.
205
+ 4. For scalar placement, alignment, and ordering clauses, call `kb_model` with `mode: "requirement"` and apply strict `fact_kind: subject` / `fact_kind: property_value` facts linked with `constrains` / `requires_property`. Model header order as indexed property keys (`nav_order_1`, `nav_order_2`, ...) against one subject region.
189
206
  5. Preserve `claim_key` / `claim_text` on every ground fact and merge every key into the requirement `logic_claims` manifest.
190
207
  6. Model UI components as `symbol` entities with `sourceFile` and `symbol_role: behavioral`, linked `implements` to the requirement.
191
- 7. `kb_validate_upsert`, create endpoints first, then sequential `kb_upsert`. Run `kb_check` with `logic-coverage`, `predicate-verifiability`, and `domain-contradictions`, then a final unfiltered `kb_check`.
208
+ 7. `kb_upsert` with `dryRun: true`, create endpoints first, then sequential `kb_upsert`. Run `kb_check` with `logic-coverage`, `predicate-verifiability`, and `domain-contradictions`, then a final unfiltered `kb_check`.
192
209
 
193
210
  Incompatible values on the same subject/property from two current requirements are rejected on write; change an intentional value via a replacement requirement linked with `supersedes`. Full payloads are in `resources/ui-requirements.md`.
194
211
 
@@ -364,7 +364,10 @@ export function launchKibiMcp(
364
364
  cwd: workspaceRoot,
365
365
  env: {
366
366
  ...env,
367
- KIBI_WORKSPACE: workspaceRoot,
367
+ // Attach without pinning: a pinned server (KIBI_WORKSPACE) disables
368
+ // per-call workspace routing, so worktree calls would be answered from
369
+ // this checkout. An operator-set KIBI_WORKSPACE still passes through.
370
+ KIBI_MCP_ATTACH_ROOT: workspaceRoot,
368
371
  // Identify the host on usage rows. This never enables telemetry;
369
372
  // KIBI_DIAGNOSTIC_MODE stays the operator's explicit opt-in and is
370
373
  // passed through untouched.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kibi-cursor",
3
3
  "displayName": "Kibi",
4
- "version": "2.2.0",
4
+ "version": "2.3.0",
5
5
  "description": "Optional Cursor adapter for Kibi. Requires project-local kibi-cli, kibi-mcp, and kibi-core (SWI-Prolog is bundled on Linux and macOS) before the bundled MCP server can start.",
6
6
  "license": "AGPL-3.0-or-later",
7
7
  "author": {
@@ -364,7 +364,10 @@ export function launchKibiMcp(
364
364
  cwd: workspaceRoot,
365
365
  env: {
366
366
  ...env,
367
- KIBI_WORKSPACE: workspaceRoot,
367
+ // Attach without pinning: a pinned server (KIBI_WORKSPACE) disables
368
+ // per-call workspace routing, so worktree calls would be answered from
369
+ // this checkout. An operator-set KIBI_WORKSPACE still passes through.
370
+ KIBI_MCP_ATTACH_ROOT: workspaceRoot,
368
371
  // Identify the host on usage rows. This never enables telemetry;
369
372
  // KIBI_DIAGNOSTIC_MODE stays the operator's explicit opt-in and is
370
373
  // passed through untouched.
@@ -7,7 +7,15 @@ export type GuidanceContext = {
7
7
  readonly workspaceTrusted: boolean;
8
8
  /** Requirements the edited file already owns, when the manifest knows them. */
9
9
  readonly linkedRequirementIds?: readonly string[];
10
+ /**
11
+ * The shared kibi-agent-core knowledge snippet for a file that implements
12
+ * requirements: titles, what the lead requirement must keep true and the
13
+ * decision behind it (edits), tests, and the next-layer calls.
14
+ */
15
+ readonly knowledge?: string | undefined;
10
16
  };
17
+ /** Cursor's own ask once the shared snippet has named the requirements. */
18
+ export declare const PRE_EDIT_FOLLOWUP = "Kibi pre-edit guidance: read those requirements with kb_query before changing behavior here; if the change contradicts one, resolve that in Kibi before writing the edit.";
11
19
  export declare function readGuidance(filePath: string, context: GuidanceContext): string | undefined;
12
20
  /**
13
21
  * Guidance emitted before an edit is written.
package/dist/guidance.js CHANGED
@@ -2,6 +2,13 @@ import { interfaceAdvisory } from "./messages.js";
2
2
  // implements REQ-cursor-kibi-plugin-v1, REQ-agent-kibi-interface-selection
3
3
  import { isDocumentationTrackedPath, isMeaningfulTrackedPath, toRepoRelativePath, } from "./path-policy.js";
4
4
  export { resolveKibiInterface } from "./kb-mcp-tools.js";
5
+ // implements REQ-cursor-kibi-plugin-v1
6
+ /** Cursor's own ask once the shared snippet has named the requirements. */
7
+ export const PRE_EDIT_FOLLOWUP = "Kibi pre-edit guidance: read those requirements with kb_query before changing behavior here; if the change contradicts one, resolve that in Kibi before writing the edit.";
8
+ function withAdvisory(context, guidance) {
9
+ const advisory = interfaceAdvisory(context.mcpState, context.workspaceTrusted);
10
+ return advisory ? [advisory, ...guidance].join("\n") : guidance.join("\n");
11
+ }
5
12
  export function readGuidance(filePath, context) {
6
13
  if (!context.hasKibi) {
7
14
  return undefined;
@@ -10,6 +17,9 @@ export function readGuidance(filePath, context) {
10
17
  if (!isMeaningfulTrackedPath(relativePath)) {
11
18
  return undefined;
12
19
  }
20
+ if (context.knowledge) {
21
+ return withAdvisory(context, [context.knowledge]);
22
+ }
13
23
  const guidance = [
14
24
  "Kibi read guidance: before changing this file, discover linked knowledge through the selected MCP or CLI JSON route.",
15
25
  `Start with kb_search, then kb_query with sourceFile="${relativePath}".`,
@@ -37,6 +47,9 @@ export function preEditGuidance(filePath, context) {
37
47
  if (isDocumentationTrackedPath(relativePath)) {
38
48
  return undefined;
39
49
  }
50
+ if (context.knowledge) {
51
+ return withAdvisory(context, [context.knowledge, PRE_EDIT_FOLLOWUP]);
52
+ }
40
53
  const linkedRequirements = context.linkedRequirementIds ?? [];
41
54
  const guidance = linkedRequirements.length > 0
42
55
  ? [
@@ -14,6 +14,8 @@ export type CursorHookResult = {
14
14
  export type HookEnvironment = {
15
15
  pluginData?: string;
16
16
  workspaceTrusted?: boolean;
17
+ /** Process environment for the telemetry opt-in; defaults to process.env. */
18
+ env?: NodeJS.ProcessEnv;
17
19
  };
18
20
  /**
19
21
  * The Kibi workspace that owns `directory`: the nearest ancestor with
@@ -3,14 +3,68 @@
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
5
  import { fileURLToPath, pathToFileURL } from "node:url";
6
+ import { appendHookUsageRows, editTraces, hookTelemetryEnabled, kbUsageTrace, readPackageVersion, } from "kibi-agent-core/hook-usage-log";
6
7
  import { stampKibiWorkspace } from "kibi-agent-core/kb-mcp-tools";
8
+ import { createEntitySummarizer, editFocus, fileKnowledgeSnippet, implementedRequirementIds, } from "kibi-agent-core/snippets";
7
9
  import { preEditGuidance, readGuidance, writeGuidance } from "./guidance.js";
8
10
  import { parseHookInput, parseStdinJson, readStdin } from "./hook-input.js";
9
11
  import { addDirtyPaths, clearSessionHookState, hasGuidedPath, loadHookState, recordKbMcpTool, recordPlanDelivered, rememberGuidedPath, resolveStateDir, } from "./hook-state.js";
10
12
  import { extractKbMcpToolCall } from "./kb-mcp-tools.js";
11
13
  import { BOOTSTRAP_REMINDER, DIRECT_KB_EDIT_WARNING, interfaceAdvisory, stopFollowupMessage, } from "./messages.js";
12
14
  import { extractExplicitPathFields, isDirectKbPath, isKbFreshnessRelevantPath, isMeaningfulTrackedPath, toRepoRelativePath, } from "./path-policy.js";
13
- import { getSourceLinkedRequirementIds } from "./source-linked-requirements.js";
15
+ import { getSourceLinkedSymbols, } from "./source-linked-requirements.js";
16
+ const MAX_LINKED_REQUIREMENTS = 3;
17
+ /**
18
+ * The shared kibi-agent-core snippet for a file that implements requirements,
19
+ * or undefined so the generic Cursor guidance applies. Test-only links
20
+ * (`covered_by`, `executable_for`) are not requirement ownership here.
21
+ */
22
+ // implements REQ-cursor-kibi-plugin-v1
23
+ function knowledgeFor(workspaceRoot, linked, surface, focus) {
24
+ if (implementedRequirementIds(linked.symbols).length === 0)
25
+ return undefined;
26
+ return fileKnowledgeSnippet({
27
+ relativePath: linked.relativePath,
28
+ symbols: linked.symbols,
29
+ surface,
30
+ focus,
31
+ summarize: createEntitySummarizer(workspaceRoot),
32
+ });
33
+ }
34
+ let cachedPackageVersion;
35
+ function packageVersion() {
36
+ // dist/hook-runner.js sits one level below the package root.
37
+ if (cachedPackageVersion !== undefined)
38
+ return cachedPackageVersion;
39
+ cachedPackageVersion = readPackageVersion(path.join(path.dirname(fileURLToPath(import.meta.url)), "..", "package.json"));
40
+ return cachedPackageVersion;
41
+ }
42
+ /**
43
+ * Opt-in (`KIBI_DIAGNOSTIC_MODE`) hook rows for the lookup-before-first-edit
44
+ * telemetry metric: Kibi lookups through MCP or the CLI, and edits with the
45
+ * requirements the edited files implement.
46
+ */
47
+ // implements REQ-cursor-kibi-plugin-v1
48
+ function recordToolTelemetry(input, workspaceRoot, stateDir, startedAt, env) {
49
+ if (!hookTelemetryEnabled(env))
50
+ return;
51
+ const kbUsage = kbUsageTrace(input.toolName, input.toolInput);
52
+ const traces = kbUsage
53
+ ? [kbUsage]
54
+ : isKnownEditableTool(input.toolName)
55
+ ? editTraces(extractExplicitPathFields(input.toolInput).map((candidate) => toRepoRelativePath(candidate, workspaceRoot)), (relativePath) => implementedRequirementIds(getSourceLinkedSymbols(workspaceRoot, relativePath, stateDir)
56
+ .symbols))
57
+ : [];
58
+ appendHookUsageRows({
59
+ host: "cursor",
60
+ packageVersion: packageVersion(),
61
+ workspaceRoot,
62
+ event: "postToolUse",
63
+ sessionId: input.conversationId,
64
+ hostTool: input.toolName,
65
+ startedAt,
66
+ }, traces, env);
67
+ }
14
68
  const editableTools = new Set([
15
69
  "Edit",
16
70
  "MultiEdit",
@@ -78,6 +132,7 @@ function resolvePrimaryPath(input) {
78
132
  return explicitPaths[0];
79
133
  }
80
134
  export async function runHook(rawInput, environment = {}) {
135
+ const startedAt = new Date();
81
136
  const input = parseHookInput(rawInput);
82
137
  const pluginData = environment.pluginData ?? process.env.PLUGIN_DATA;
83
138
  const stateDir = resolveStateDir(pluginData, input.conversationId);
@@ -125,12 +180,14 @@ export async function runHook(rawInput, environment = {}) {
125
180
  if (hasGuidedPath(state, "pre-edit", relativePath)) {
126
181
  return emptyResult();
127
182
  }
183
+ const linked = getSourceLinkedSymbols(cwd, primaryPath, stateDir);
128
184
  const guidance = preEditGuidance(primaryPath, {
129
185
  cwd,
130
186
  hasKibi: kibiReady,
131
187
  mcpState: state.mcpState,
132
188
  workspaceTrusted,
133
- linkedRequirementIds: getSourceLinkedRequirementIds(cwd, primaryPath, stateDir),
189
+ linkedRequirementIds: implementedRequirementIds(linked.symbols).slice(0, MAX_LINKED_REQUIREMENTS),
190
+ knowledge: knowledgeFor(cwd, linked, "edit", editFocus(path.resolve(cwd, primaryPath), input.toolInput)),
134
191
  });
135
192
  if (!guidance) {
136
193
  return emptyResult();
@@ -153,6 +210,7 @@ export async function runHook(rawInput, environment = {}) {
153
210
  hasKibi: kibiReady,
154
211
  mcpState: state.mcpState,
155
212
  workspaceTrusted,
213
+ knowledge: knowledgeFor(cwd, getSourceLinkedSymbols(cwd, primaryPath, stateDir), "read"),
156
214
  });
157
215
  if (!guidance) {
158
216
  return { permission: "allow" };
@@ -164,6 +222,14 @@ export async function runHook(rawInput, environment = {}) {
164
222
  };
165
223
  }
166
224
  case "postToolUse": {
225
+ if (kibiReady) {
226
+ try {
227
+ recordToolTelemetry(input, cwd, stateDir, startedAt, environment.env);
228
+ }
229
+ catch {
230
+ // Telemetry is best effort and must never change the hook's output.
231
+ }
232
+ }
167
233
  const kbToolCall = extractKbMcpToolCall(input.toolName, input.toolInput);
168
234
  if (kbToolCall) {
169
235
  recordKbMcpTool(stateDir, kbToolCall.toolName, {
@@ -199,6 +265,7 @@ export async function runHook(rawInput, environment = {}) {
199
265
  hasKibi: kibiReady,
200
266
  mcpState: state.mcpState,
201
267
  workspaceTrusted,
268
+ knowledge: knowledgeFor(cwd, getSourceLinkedSymbols(cwd, primaryPath, stateDir), "read"),
202
269
  });
203
270
  if (!guidance) {
204
271
  return emptyResult();
@@ -1,6 +1,6 @@
1
1
  {
2
- "kibi-bootstrap/SKILL.md": "5bb63f0e5ee5ba7e60ef3dc7758ad84ee39e83ffeb46b9f038221bc48a656676",
3
- "kibi-bootstrap/resources/bootstrap.md": "14531116e8a0efc69b7ccb105afebeeaa2185e720bad2d5bebadc6635598a041",
2
+ "kibi-bootstrap/SKILL.md": "de228e10d65b428d4ea3e2229fa106407da60521fb8da8387ce6a52242b3a349",
3
+ "kibi-bootstrap/resources/bootstrap.md": "566f44253c7f1258a56dc4f0770128d451ca7757c6901febc5a0e596ed4621e0",
4
4
  "kibi-bootstrap/resources/branch-lifecycle.md": "c854264ce888439140883a3fc636db5e522f020dd27b30a5c1ecc4105b64ed13",
5
5
  "kibi-bootstrap/resources/operation-access.md": "b5a6a59e72d800c376e7fad79132897623c32a0ce152a1e8d73f9628b444db51",
6
6
  "kibi-bootstrap/resources/source-authoring.md": "bf296e62f69474e01797d6cb9469bf624551dca834dd188abb6e705bd96fa586",
@@ -13,15 +13,15 @@
13
13
  "kibi-traceability/resources/operation-access.md": "39f7972ab7f4ae7479e78f7072bb50e8e6c4cdf4f857425f69d2522d37db437c",
14
14
  "kibi-traceability/resources/source-authoring.md": "408c6ee2bef1b84e0194c0538ef929c26a0a617e631b2234247388140dbbdd08",
15
15
  "kibi-traceability/resources/traceability.md": "38c290a0bc71bd1692e115f22694743946e2f69630e134acfd43cee5f613fb88",
16
- "kibi-usage/SKILL.md": "94982ae809de80467e5f2417ca64235dae0f81166407cdb8d0f66f322bd9efc8",
16
+ "kibi-usage/SKILL.md": "251f72f95551c17ac85453024a9e1a78cd3261f62ad13ebea9d2397fdcdad856",
17
17
  "kibi-usage/resources/branch-lifecycle.md": "f1bf359e9826e83c548f3cd0287f8175a62456527b0132b06b3f9f74aa59b7d6",
18
- "kibi-usage/resources/fact-lanes.md": "7ac928cc6b3d189eee6a9cda282918677d5a222cd7ba9b7f324e6553cd3adce8",
19
- "kibi-usage/resources/kb-improvement.md": "17e8b6cf6a0dd43b443a2bfd92e7205d099647a5f1c75fe85413a6cea63d86c6",
20
- "kibi-usage/resources/logic-ir.md": "151675d0ffa813cb9e271084102a3af42de369b8f9a0c64866af0cdc4d924063",
21
- "kibi-usage/resources/operation-access.md": "df8e84258f4e4855c08a9d24f7704fd540f0ea4295f5f255a4a9500a450ccf80",
18
+ "kibi-usage/resources/fact-lanes.md": "97f5a9aaa331835018312d6684038c2b2a0c383827716fb7c9de3faedbee622b",
19
+ "kibi-usage/resources/kb-improvement.md": "a8408fce27342bdce6415a6718599e53fe00bb33aa1fd3dc42353ec6f61adcd7",
20
+ "kibi-usage/resources/logic-ir.md": "0e8ce8aad07433ab4803ec169149ff6c4e1cf8cf010af18fa6fd67862d9be807",
21
+ "kibi-usage/resources/operation-access.md": "eb455796c066787ffd3fae8db0db1d3e87a84265a57f06ae61e30103cd6aed66",
22
22
  "kibi-usage/resources/proof.md": "7391046fbdeece4858b668360c60755f184af6dfedda9dbc67e2fa4574dbce7f",
23
23
  "kibi-usage/resources/relationship-directions.md": "0fdd67032c2d15299f772845fc4f807eb9435b09507bd87a5911ab33db2f143d",
24
24
  "kibi-usage/resources/source-authoring.md": "80978cea0614484292c7a70d511a3f50458f48ef976bf0675b8bb96abe9d3d36",
25
- "kibi-usage/resources/ui-requirements.md": "b7c31ab1affa3ab25ae5242d8fd8c4d546532d1cafc65d84088375317c1682cc",
26
- "kibi-usage/resources/workflows.md": "52cadc2b1e41af7d0c3129b721d81bb542fefb97113ba3a7c817f7ab7a1f787e"
25
+ "kibi-usage/resources/ui-requirements.md": "ea8e8a4c546acb668963ec354cd31711152c3ca3bc7d3078d2252ff9e2cd44a3",
26
+ "kibi-usage/resources/workflows.md": "bde1cc6f1aaba6cbc1db59cfe23f01986bf95e02e471f2d066ce428d5a81e1f0"
27
27
  }
@@ -2,7 +2,7 @@
2
2
  id: kibi-bootstrap
3
3
  name: kibi-bootstrap
4
4
  description: Bootstrap Kibi from the current Git checkout and the project's existing knowledge sources, with a source interview, cited intent claims, preview approval, source-first writes, and repair-safe completion.
5
- version: 3.1.0
5
+ version: 3.1.1
6
6
  kibiCompatibility: ">=1.0.0"
7
7
  tags:
8
8
  - kibi
@@ -87,6 +87,11 @@ Finish with `kb_check` and `kb_status`.
87
87
  Consume the versioned `kibiProtocol: 1` result envelope: inspect `status`, `effects`,
88
88
  `diagnostics`, and `nextActions`. On `committed_with_repairs`, execute required
89
89
  repair actions and never retry the original mutation.
90
+ On `BOOTSTRAP_PLAN_INVALID`, obtain a corrected preview and approval before
91
+ applying. On `BOOTSTRAP_PLAN_REJECTED`, inspect committed `data.actionResults`
92
+ and re-plan from the current state; the journal is terminal and cannot recover.
93
+ Review `suppressedCandidates`, `sourceOnlySignals`, and diagnostics for invalid,
94
+ ungroundable, unreadable, or over-limit candidates before approving a plan.
90
95
 
91
96
  Kibi may author tracked Markdown/YAML/manifests and relationship shards
92
97
  transactionally, but never Git-stages or commits them. Never read or edit
@@ -14,3 +14,9 @@ approved hash; inspect its typed result
14
14
  and follow `nextActions` if it returns `committed_with_repairs`. Direct
15
15
  `kb_upsert` is forbidden for every bootstrap task; never manually replay the
16
16
  plan through it.
17
+
18
+ `BOOTSTRAP_PLAN_INVALID` fails before bootstrap writes or a new journal; request
19
+ a corrected plan. `BOOTSTRAP_PLAN_REJECTED` reports a deterministic failure and
20
+ may include earlier committed `data.actionResults`. Re-plan from the current
21
+ state; its terminal journal cannot recover. Review candidate suppressions and
22
+ cited authoring follow-ups, including any `over_limit` entries, before approval.