kibi-cursor 2.0.0 → 2.1.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 (41) hide show
  1. package/.cursor-plugin/plugin.json +1 -1
  2. package/CHANGELOG.md +84 -0
  3. package/README.md +1 -1
  4. package/agent-plugin/plugin.json +1 -1
  5. package/agent-plugin/skills/kibi-usage/SKILL.md +10 -3
  6. package/agent-plugin/skills/kibi-usage/resources/fact-lanes.md +4 -0
  7. package/agent-plugin/skills/kibi-usage/resources/proof.md +45 -0
  8. package/agent-plugin/skills/kibi-usage/resources/relationship-directions.md +35 -17
  9. package/agent-plugin/skills/kibi-usage/resources/source-authoring.md +36 -0
  10. package/agent-plugin/skills/kibi-usage/resources/workflows.md +52 -1
  11. package/bin/launch-kibi-mcp.mjs +8 -1
  12. package/dist/.cursor-plugin/plugin.json +1 -1
  13. package/dist/bin/launch-kibi-mcp.mjs +8 -1
  14. package/dist/guidance.d.ts +11 -0
  15. package/dist/guidance.js +39 -5
  16. package/dist/hook-input.js +7 -4
  17. package/dist/hook-runner.js +36 -6
  18. package/dist/hook-state-storage.js +55 -2
  19. package/dist/hook-state.d.ts +4 -2
  20. package/dist/hook-state.js +30 -7
  21. package/dist/kb-mcp-tools.d.ts +5 -7
  22. package/dist/kb-mcp-tools.js +6 -126
  23. package/dist/messages.js +3 -8
  24. package/dist/path-policy.js +17 -177
  25. package/dist/skills/.canon-hash.json +6 -6
  26. package/dist/skills/kibi-usage/SKILL.md +10 -3
  27. package/dist/skills/kibi-usage/resources/fact-lanes.md +4 -0
  28. package/dist/skills/kibi-usage/resources/proof.md +45 -0
  29. package/dist/skills/kibi-usage/resources/relationship-directions.md +35 -17
  30. package/dist/skills/kibi-usage/resources/source-authoring.md +36 -0
  31. package/dist/skills/kibi-usage/resources/workflows.md +52 -1
  32. package/dist/source-linked-requirements.d.ts +16 -0
  33. package/dist/source-linked-requirements.js +55 -0
  34. package/package.json +4 -1
  35. package/skills/.canon-hash.json +6 -6
  36. package/skills/kibi-usage/SKILL.md +10 -3
  37. package/skills/kibi-usage/resources/fact-lanes.md +4 -0
  38. package/skills/kibi-usage/resources/proof.md +45 -0
  39. package/skills/kibi-usage/resources/relationship-directions.md +35 -17
  40. package/skills/kibi-usage/resources/source-authoring.md +36 -0
  41. package/skills/kibi-usage/resources/workflows.md +52 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kibi-cursor",
3
3
  "displayName": "Kibi",
4
- "version": "2.0.0",
4
+ "version": "2.1.0",
5
5
  "description": "Optional Cursor adapter for Kibi. Requires SWI-Prolog 9+ and project-local kibi-cli, kibi-mcp, and kibi-core before the bundled MCP server can start.",
6
6
  "license": "AGPL-3.0-or-later",
7
7
  "author": {
package/CHANGELOG.md CHANGED
@@ -1,5 +1,89 @@
1
1
  # kibi-cursor
2
2
 
3
+ ## 2.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - f01838e: The Cursor plugin now asks the agent to consult Kibi before it edits a file, not only after. Every nudge used to fire once the change was already written — the post-edit message opened with "After editing" twice — so the plugin could only ever prompt repair, never inform the change. Before an edit, the plugin now names only requirements the file explicitly implements and asks for them to be read first, which is the one point where retrieval can still change what gets written.
8
+
9
+ - Emit source-linked pre-edit guidance from `preToolUse` for edit-like tools, resolved synchronously from the symbol manifest so no KB round-trip is added to the edit path.
10
+ - Name up to three `implements` requirement targets for the file, or ask for discovery and ownership when no requirement ownership is known.
11
+ - Narrow the post-edit message to the impact review that only becomes possible once the change exists, and stop repeating the retrieval ask there.
12
+ - Track pre-edit guidance in its own hook-state bucket so it is emitted once per path without suppressing the post-edit review.
13
+
14
+ ### Patch Changes
15
+
16
+ - 35cd120: The ZCode, Codex, and Cursor plugins now recognize Kibi tools when the host
17
+ reports them with a prefix, such as `mcp__kibi__kb_check`. Before this fix,
18
+ an agent that correctly ran an impact check through a prefixed tool name
19
+ still got a stop reminder to run it, because the plugin never saw the check.
20
+
21
+ - `kb-mcp-tools.ts` in each adapter gains `canonicalKbToolName`, which strips
22
+ `mcp__<server>__`, `MCP:`, and `kibi_` prefixes before matching `kb_*`
23
+ operations.
24
+ - The Codex hook bundle is regenerated.
25
+
26
+ - 25f11b1: The badge that `kibi init --github` adds to your README now links to the published explanation of the `% proven` metric at https://looted.github.io/kibi/ instead of the GitHub rendering of the Markdown source. The Kibi documentation site moved to the root of that domain, with the requirement-health report still under `/kibi-report/`. The Cursor and OpenCode package READMEs also link to the published guides, so the links work when you read them on npm.
27
+
28
+ - cli: `KIBI_METRIC_DOCS_URL` points at `https://looted.github.io/kibi/guide/github-integration.html#what-the-badge-means`.
29
+ - cursor, opencode: README setup and troubleshooting links point at the published guide pages instead of repository-relative or GitHub blob URLs.
30
+ - repo tooling (not published): the docs site builds into the GitHub Pages root and renders `llms.txt` as one H2 link list per catalog group from the shared page metadata.
31
+
32
+ - 5a06c03: Kibi's agent plugins now share one fast, consistent implementation for source-path classification, Kibi MCP tool recognition, and symbol-manifest indexing. Codex and ZCode now recognize production code outside `src/`, while Cursor reuses the same size-and-mtime-keyed scanner as Claude instead of parsing the full symbol manifest before an edit.
33
+
34
+ - Add `kibi-agent-core` as the common Node 18-compatible hook-helper package.
35
+ - Keep host adapters thin while preserving their host-specific event and state contracts.
36
+ - Replace Cursor's YAML parser dependency with the shared cached line scanner.
37
+
38
+ - f01838e: Usage telemetry stays off by default for every client, and there is now a supported way to turn it on. Previously the only way to capture usage was to hand-write an MCP command line with `--diagnostic-mode`, which meant anyone using a shipped plugin recorded nothing at all and had no documented alternative. Operators can now opt in with an environment variable, and once they do, each row identifies the host, package version, and checkout that produced it, so behavior can be compared across editors, worktrees, and Kibi versions.
39
+
40
+ - Honor `KIBI_DIAGNOSTIC_MODE=1` alongside the existing `--diagnostic-mode` flag, for hosts where a plugin owns the MCP command line.
41
+ - Stamp `interface`, `host`, `package_version`, and `workspace_root` on every usage row.
42
+ - Set `KIBI_MCP_HOST` from the Cursor and Codex launchers for attribution only; it never enables logging, and installing or enabling a plugin never starts telemetry.
43
+ - Stop the bundled Cursor worktree resolver from hard-coding `--diagnostic-mode`, so a shipped launcher cannot enable capture on an operator's behalf.
44
+ - Document the opt-in, what a row contains, and how to opt out in `docs/mcp-reference.md`.
45
+
46
+ - 0128b56: Kibi now helps agents keep one shared vocabulary instead of letting every requirement invent its own. `kibi check` warns when two unrelated requirements state the same obligation. Units are compared in canonical form, so "30 min" matches "1800 s", and each warning names the exact facts involved. It also flags subject keys copied from a requirement ID, subject keys that don't follow `component.aspect`, predicates whose arguments read like prose, and entity files whose name doesn't match their ID. All of these are non-blocking warnings or info notes, so existing knowledge bases keep passing.
47
+
48
+ When you model a new requirement, Kibi now ranks the subjects that already exist and either reuses one or explicitly declares a new one. It also flags claims that look like possible duplicates. An intentional restatement can be recorded with the new `restates` relationship. Skills and docs now recommend naming entities by the behavior they govern (`REQ-cli-gc`) instead of a sequence number (`REQ-042`). Existing numbered IDs stay valid.
49
+
50
+ Predicate schemas can now declare the allowed values for an argument, plus the old spellings that map onto them. New facts must use those values. `kibi check` reports predicate facts that don't match any schema, and `kibi migrate` can fix the mechanical cases after you approve the plan hash. It moves a fact to the only namespace whose schema matches, and rewrites old spellings to the declared value. Everything that needs judgment stays a review item.
51
+
52
+ - core: new `semantic_quality.pl` (`entity-id-style`, `domain-redundancy`, `domain-implication`, `subject-key-identity`, `subject-key-shape`, `ontology-quality`) and `units.pl`. Unit canonicalization is used for comparison only, and unknown or ambiguous units such as `KB` are never equated. Adds the `restates` req→req relationship and an optional `diagnosticSeverity` in the rule registry. Adds `:- encoding(utf8)` to modules that contain non-ASCII text.
53
+ - cli/mcp: `restates` is wired through the extractors, schemas, and mutation paths. `entity-id-style` warnings are reported on `kb_upsert` creates and on staged added or renamed entity files. `kb_model_requirement` returns `vocabularyAlignment` (subject decision, candidates, redundancy candidates, stamps, `fallbackUsed`). Ontology-quality thresholds can be set with `KIBI_ONTOLOGY_QUALITY_MAX_SINGLETON_RATIO` / `KIBI_ONTOLOGY_QUALITY_MIN_FACTS`. `kb_compile_intent` create mode now keeps a caller-supplied `requirementId`. `kibi check --staged` now also prints its pass line when metadata-only staged changes have only advisory findings, matching the staged-symbol path.
54
+ - cli/mcp: `predicate_schema` facts accept `argument_constants` and `argument_aliases`, stored like `rule_ir` as JSON. `kb_upsert` / `kb_validate_upsert` reject malformed vocabularies and predicate facts that use undeclared values or aliases. `kb_suggest_predicates` binds aliases to their constant and leaves undeclared values unbound. The new advisory TypeScript rule `predicate-schema-conformance` checks predicate facts against project schemas and the built-in catalog. Its mechanical repairs become automatic `predicate_schema_alignment` migration actions that carry the exact `kb_upsert` input and re-read the fact before writing.
55
+ - core: `ontology-quality` findings name the prose-like arguments.
56
+ - plugin-sdk: new `kibi.vocabulary-alignment.v1` capability (`rankSubjects`, `compareClaims`) with result validators.
57
+ - plugin-builtin: deterministic offline provider (IDF-weighted subject ranking and negation- and quantity-aware claim similarity).
58
+ - plugin-jev: Jev-backed provider. It runs in replace, augment, or shadow mode with builtin fallback, and makes network calls only when it is activated for `kb_model_requirement`. `kb_check` never calls a provider.
59
+ - runtime and agent adapters: regenerated skill mirrors with the naming guidance and `restates` direction docs.
60
+
61
+ - Updated dependencies [5a06c03]
62
+ - kibi-agent-core@0.1.0
63
+
64
+ ## 2.0.1
65
+
66
+ ### Patch Changes
67
+
68
+ - 96a1ebd: Local Cursor MCP builds now compile plugin SDK/builtin dist before the CLI, so a fresh checkout no longer fails with a missing `kibi-plugin-builtin` type package.
69
+
70
+ - `build:cli-stack` runs plugin-sdk + plugin-builtin + CLI
71
+ - Worktree resolver uses that stack instead of `build:cli` alone
72
+
73
+ - 188f875: No user-facing behavior change: `kibi-runtime` now resolves its bundled-skills directory lazily on first use instead of at import time, `isWithinRoot` drops a redundant same-path comparison, `kibi-cursor` drops a provably dead `planDelivered` early return and an always-true stdin branch, and the hook runners' stdin buffering is simplified to an unconditional `Buffer.from`. The reshaping lets the new mutation-testing suite (`docs/mutation-testing.md`, run via `bun run test:mutation`) prove these paths exhaustively — the suite holds a 100% mutation score over `kibi-runtime`, `kibi-codex`, and `kibi-cursor` sources.
74
+ - db07d8f: Proof diagnostics now agree with the Prolog decision: a structural type-shape unit contract is shown as qualifying, `kibi proof impact` compares against the Git HEAD baseline and exits 0 after a successful report, and mixed-role symbols fail the strict proof integrity gate.
75
+
76
+ - Mode-aware candidate evaluation in Prolog; receipt fallback uses `test_receipt_evidence(Context, TestId, Evidence)`.
77
+ - `proof impact` reads `HEAD:proof/baseline.json` with no worktree fallback; diagnostic exit 0.
78
+ - Strict proof workflow and baseline checker include canonical `symbol-traceability`.
79
+
80
+ - f33a665: Proof failures now name the exact requirement, symbol, and why each `covered_by` candidate did not qualify, without changing what counts as proven. Agents can inspect a requirement with `kibi proof explain` and compare current proof state to the committed `proof/baseline.json` snapshot with `kibi proof impact`, instead of reverse-engineering Prolog or guessing from aggregate counts.
81
+
82
+ - Keep `kibi.requirement-proof.v3` and add additive production-symbol `explanations` plus TEST `testResolutions` on the same Proof.
83
+ - Ratchet `proof/baseline.json` to v2 with compact requirement fingerprints; aggregate counts stay the ratchet.
84
+ - Add `kibi proof explain` and `kibi proof impact` as Proof projections, mixed-role leftovers in `symbol-traceability`, and advisory `proof-contract-symbols`.
85
+ - Document the proof-regression workflow in `kibi-usage` 2.1.3.
86
+
3
87
  ## 2.0.0
4
88
 
5
89
  ### Major Changes
package/README.md CHANGED
@@ -21,7 +21,7 @@ swipl --version
21
21
  npm exec -- kibi doctor
22
22
  ```
23
23
 
24
- Full setup: [docs/install.md](https://github.com/Looted/kibi/blob/develop/docs/install.md).
24
+ Full setup: [installation guide](https://looted.github.io/kibi/guide/install.html#optional-cursor-plugin).
25
25
 
26
26
  Add this plugin only after the base packages work in your project.
27
27
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
3
3
  "name": "kibi",
4
- "version": "2.0.0",
4
+ "version": "2.1.0",
5
5
  "description": "Repo-local, per-branch, queryable knowledge base. Portable Agent Plugin packaging Kibi's Agent Skills and MCP server.",
6
6
  "author": { "name": "Kibi" },
7
7
  "homepage": "https://github.com/Looted/kibi/blob/develop/docs/install.md",
@@ -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.1.2
5
+ version: 2.2.0
6
6
  kibiCompatibility: ">=1.0.0"
7
7
  tags:
8
8
  - kibi
@@ -59,7 +59,11 @@ mutability, and Prolog requirements of each operation.
59
59
  ## Safe workflow
60
60
 
61
61
  1. Always discover before you mutate: start with `kb_search`, then exact-filter with `kb_query`. Use
62
- `kb_status` when branch or freshness confidence matters.
62
+ `kb_status` when branch or freshness confidence matters. `kb_search` ranks
63
+ lexically unless you pass `rankingMode: "intent-v1"`, `semanticFacets`, or
64
+ `sourceLocations`; use intent mode with grounded facets for conceptual
65
+ questions and before changing a source file, and keep lexical search for
66
+ literal identifiers. See `resources/workflows.md` for the mode recipe.
63
67
  2. Resolve genuine ambiguity with the human; use semantic advisor/modeling
64
68
  operations for deterministic interpretation and typed facts.
65
69
  3. Create endpoints before relationships and upsert small batches sequentially.
@@ -133,6 +137,9 @@ safe normative claims; use `observation` or `meta` for bug/workaround notes and
133
137
  tests, symbol ownership, and fresh proof-bearing receipts before claiming proof.
134
138
  For an existing product KB that needs semantic backfill, read
135
139
  `resources/kb-improvement.md`, and `resources/proof.md` for the proof workflow.
140
+ When a proof ratchet fails, follow Debugging proof regressions in
141
+ `resources/proof.md`: use `kibi proof explain` and compare current proof state
142
+ to committed `proof/baseline.json` with `kibi proof impact`.
136
143
 
137
144
  ## Predicate Ontology Decision Tree
138
145
 
@@ -157,7 +164,7 @@ Represent implementation ownership with a `symbol` entity that has
157
164
  `sourceFile`, `implements` to the requirement, and `covered_by` to the test.
158
165
  Prolog `symbol-coverage` also requires the test to `validates` the requirement
159
166
  (or the requirement `verified_by` the test). `covered_by` alone is not
160
- enough. Do not rely on legacy `// implements REQ-xxx` comments as the
167
+ enough. Do not rely on legacy `// implements REQ-<area>-<behavior>` comments as the
161
168
  traceability record.
162
169
 
163
170
  ## Complete Logical Coverage
@@ -55,6 +55,10 @@ relationship: { type: requires_predicate, from: REQ-EDITOR-DRAFT-AUTOSAVE, to: F
55
55
 
56
56
  The project-local schema endpoint must exist before this fact is linked. When ontology extension is explicitly authorized, define it first with `fact_kind: predicate_schema`, `predicate_name`, `predicate_arity`, and equally sized `argument_names` and `argument_types`. Without an authorized stable signature, record `review:ontology-gap` instead of inventing a schema.
57
57
 
58
+ ### Closed argument vocabularies
59
+
60
+ A schema can close an argument with `argument_constants` (allowed values keyed by argument name) and map older spellings with `argument_aliases`. Reuse a declared constant; `kb_upsert` rejects any other value and names the constant to use for an alias. When a genuinely new value is needed, extend `argument_constants` on the schema first. To converge existing facts, declare aliases for their spellings and let `kibi migrate` rewrite them (`predicate_schema_alignment` actions). Close only arguments with a natural shared vocabulary, such as the governed component or a severity; forcing distinct obligations into a few constants makes different requirements share one ground term.
61
+
58
62
  ### Deny predicate
59
63
 
60
64
  Claim: “Suspended users must not publish articles.” When `permission_rule` fits, preserve its positive schema name and encode prohibition as polarity:
@@ -103,3 +103,48 @@ re-run `kibi prove` for the affected selection, then confirm `kb_status` and
103
103
  `kb_coverage` before handoff.
104
104
 
105
105
  Full reference: `docs/proving-requirements.md`.
106
+
107
+ ## Debugging proof regressions
108
+
109
+ When a proof ratchet fails, diagnose first. Do not treat
110
+ `proof/baseline.json` as the thing to edit.
111
+
112
+ 1. Do not refresh `proof/baseline.json` as the first fix.
113
+ 2. Identify the exact requirement and symbol responsible for the regression.
114
+ 3. Use Kibi proof diagnostics rather than reverse-engineering
115
+ `requirement_proof.pl`:
116
+
117
+ ```bash
118
+ kibi proof explain REQ-<id>
119
+ kibi proof explain SYM-<id>
120
+ kibi proof impact
121
+ ```
122
+
123
+ `kibi proof impact` compares the current Proof projection to
124
+ `HEAD:proof/baseline.json` (the committed ratchet snapshot, not the
125
+ working-tree file). It is diagnostic: fingerprint differences are reported
126
+ and the command exits 0 on successful evaluation. The strict ratchet remains
127
+ `scripts/check-proof-baseline.mjs`.
128
+ 4. For `missing_production_symbol_coverage`, inspect symbol role, owning
129
+ requirement, `covered_by`, candidate test scope, the requirement scenario
130
+ chain, and the current proof receipt. `kibi proof explain` prints those as
131
+ three labeled blocks so they cannot be confused:
132
+ `required_proofs` (TEST contract obligations), `executable_for` (test-code
133
+ identity), and `covered_by` (production coverage candidates with primary
134
+ plus optional secondary reasons).
135
+ 5. A behavioral production symbol requires qualifying behavioral/E2E evidence
136
+ under the current proof model.
137
+ 6. Unit coverage can satisfy structural/type-shape requirements only when the
138
+ symbol genuinely represents structural shape and the proof model allows it.
139
+ 7. `executable_for` identifies executable test code. Never use it on
140
+ production helpers merely to remove production coverage obligations.
141
+ 8. Do not trust TEST names. Resolve
142
+ `TEST -> proof_contract.required_proofs -> SYM -> source` and inspect what
143
+ the executable test actually exercises. Kibi does not infer “this TEST name
144
+ does not match that source file.”
145
+ 9. A passing proof producer does not automatically make every authored
146
+ `covered_by` relationship semantically correct.
147
+ 10. Prefer one meaningful E2E scenario covering multiple internal functions
148
+ plus focused unit tests for edge cases, rather than an E2E test per helper.
149
+ 11. Refresh the baseline only after a genuine intentional proof-state
150
+ improvement requires the ratchet snapshot to be updated.
@@ -12,6 +12,7 @@
12
12
  | `constrains` | req -> fact(subject) | Requirement constrains a strict-lane domain fact |
13
13
  | `requires_property` | req -> fact(property_value) | Requirement requires a specific property value fact |
14
14
  | `supersedes` | new-req -> old-req | New requirement formally replaces an old requirement |
15
+ | `restates` | req -> req | Requirement intentionally restates another current requirement (for example a product requirement echoed in a platform requirement); suppresses `domain-redundancy` for that pair without retiring either side |
15
16
  | `covered_by` | symbol -> test | Production symbol has test coverage evidence |
16
17
 
17
18
  ## Valid Payload Examples
@@ -20,32 +21,32 @@
20
21
  ```yaml
21
22
  relationships:
22
23
  - type: implements
23
- from: SYM-001
24
- to: REQ-001
24
+ from: SYM-operation-execute-check
25
+ to: REQ-cli-check
25
26
  ```
26
27
 
27
28
  ### specified_by
28
29
  ```yaml
29
30
  relationships:
30
31
  - type: specified_by
31
- from: REQ-001
32
- to: SCEN-001
32
+ from: REQ-mcp-search-discovery
33
+ to: SCEN-mcp-search-discovery
33
34
  ```
34
35
 
35
36
  ### verified_by
36
37
  ```yaml
37
38
  relationships:
38
39
  - type: verified_by
39
- from: REQ-001
40
- to: TEST-001
40
+ from: REQ-mcp-search-discovery
41
+ to: TEST-mcp-search-discovery
41
42
  ```
42
43
 
43
44
  ### validates
44
45
  ```yaml
45
46
  relationships:
46
47
  - type: validates
47
- from: TEST-001
48
- to: SCEN-001
48
+ from: TEST-mcp-search-discovery
49
+ to: SCEN-mcp-search-discovery
49
50
  ```
50
51
 
51
52
  ### executable_for
@@ -53,39 +54,56 @@ relationships:
53
54
  relationships:
54
55
  - type: executable_for
55
56
  from: SYM-test-login
56
- to: TEST-001
57
+ to: TEST-mcp-search-discovery
57
58
  ```
58
59
 
59
60
  ### constrains
60
61
  ```yaml
61
62
  relationships:
62
63
  - type: constrains
63
- from: REQ-019
64
- to: FACT-USER-ROLE
64
+ from: REQ-cli-check
65
+ to: FACT-SUBJECT-KIBI-CHECK
65
66
  ```
66
67
 
67
68
  ### requires_property
68
69
  ```yaml
69
70
  relationships:
70
71
  - type: requires_property
71
- from: REQ-019
72
- to: FACT-LIMIT-3
72
+ from: REQ-cli-check
73
+ to: FACT-PROP-CHECK-FAILURE-EXIT-CODE
73
74
  ```
74
75
 
75
76
  ### supersedes
76
77
  ```yaml
77
78
  relationships:
78
79
  - type: supersedes
79
- from: REQ-001-v2
80
- to: REQ-001
80
+ from: REQ-opencode-kibi-briefing-v2
81
+ to: REQ-opencode-kibi-briefing-v1
81
82
  ```
82
83
 
84
+ A `-v2` suffix is acceptable only for a direct superseding replacement like
85
+ this one; otherwise name the new requirement by the behavior it governs.
86
+
87
+ ### restates
88
+ ```yaml
89
+ # Illustrative: a product requirement echoes a platform requirement verbatim.
90
+ relationships:
91
+ - type: restates
92
+ from: REQ-billing-invoice-retention
93
+ to: REQ-platform-record-retention
94
+ ```
95
+
96
+ Use `restates` only when two current requirements deliberately ground the same
97
+ logical term (same predicate, property tuple, or rule semantic key). It keeps
98
+ both requirements current and tells `domain-redundancy` the duplication is
99
+ intentional. If one requirement replaces the other, use `supersedes` instead.
100
+
83
101
  ### covered_by
84
102
  ```yaml
85
103
  relationships:
86
104
  - type: covered_by
87
- from: SYM-handler
88
- to: TEST-005
105
+ from: SYM-operation-execute-check
106
+ to: TEST-mcp-search-discovery
89
107
  ```
90
108
 
91
109
  ## Invalid Test-Fact Shortcuts
@@ -29,3 +29,39 @@ Cancellation follows the same rule: wait for the terminal journal state. A
29
29
  pre-commit rollback is retryable, a committed source with a failed derivative
30
30
  is repairable, and an indeterminate outcome is non-retryable until its recovery
31
31
  action resolves the journal.
32
+
33
+ ## Naming entities
34
+
35
+ Name every entity by what it governs, the way you would name a source file.
36
+ Never choose "the next number": parallel branches pick the same next number and
37
+ collide even when they touch unrelated behavior.
38
+
39
+ - Use `<TYPE>-<area>-<behavior>` in kebab-case, with the type prefix kept
40
+ uppercase: `REQ-cli-gc`, `SCEN-mcp-search-discovery`,
41
+ `TEST-mcp-search-discovery`, `ADR-capability-plugins-v1`,
42
+ `EVT-exact-branch-store-ensure`, and a flag named after its gate such as
43
+ `FLAG-scip-symbol-extraction`.
44
+ - The filename stem equals the frontmatter `id`
45
+ (`.kb/requirements/REQ-cli-gc.md` has `id: REQ-cli-gc`). Always set `id`
46
+ explicitly; a missing `id` falls back to a path-and-title hash that changes
47
+ when the file is renamed.
48
+ - Before creating an entity, `kb_search` the area. If an existing entity already
49
+ covers the behavior, update it, or create a replacement and link it with
50
+ `supersedes`. A `-v2` suffix is acceptable only for that direct superseding
51
+ replacement.
52
+ - A name collision with another branch usually means the same work was done
53
+ twice. Reconcile the two entities; do not rename one of them to dodge the
54
+ collision.
55
+ - The area prefix is for humans. Whether two requirements are about the same
56
+ thing is decided by their facts: a shared `subject_key` and identical
57
+ predicate or property signatures, which `domain-redundancy` and
58
+ `domain-contradictions` compare deterministically. Reuse existing subject keys
59
+ (dotted `component.aspect[.sub]`, lowercase snake segments such as
60
+ `kibi.cli.check.staged`) instead of deriving a subject from the requirement
61
+ ID.
62
+
63
+ `entity-id-style` reports new purely numeric IDs (`REQ-123`) and IDs whose
64
+ filename stem differs from `id` as non-blocking quality diagnostics. Legacy
65
+ numbered entities created before the naming standard are grandfathered and are
66
+ not renamed, because code comments such as `// implements REQ-003` still
67
+ reference them.
@@ -33,11 +33,62 @@ surfaces are a release defect: require a new package version and label any
33
33
  project override temporary. This skill never selects a package manager or
34
34
  edits dependency configuration.
35
35
 
36
+ ## Choosing a discovery mode
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.
42
+
43
+ - **Exact identity** — you already know the ID. Use `kb_query`, not search.
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:
48
+
49
+ ```json
50
+ {
51
+ "query": "declined card during checkout",
52
+ "rankingMode": "intent-v1",
53
+ "semanticFacets": {
54
+ "actors": ["shopper"],
55
+ "actions": ["pay"],
56
+ "objects": ["card"],
57
+ "constraints": ["declined"]
58
+ }
59
+ }
60
+ ```
61
+
62
+ - **Before changing code** — pass the file you are about to edit as a source
63
+ location, so results are matched against source-linked symbols and return
64
+ source evidence:
65
+
66
+ ```json
67
+ {
68
+ "query": "checkout total rounding",
69
+ "rankingMode": "intent-v1",
70
+ "sourceLocations": [{ "path": "src/checkout.ts", "symbol": "computeTotal" }]
71
+ }
72
+ ```
73
+
74
+ Supply facets only from the request, the code, or prior results. Inventing
75
+ facets fabricates evidence and biases ranking. Intent mode abstains below
76
+ `minScore` instead of returning weak matches; an abstention is an explicit
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.
80
+
81
+ Results are summaries by default: identifying metadata, score, reasons, and a
82
+ snippet. Read them to pick candidates, then `kb_query` those IDs for full
83
+ bodies, or pass `fields: "full"` when you genuinely need every body. Extract
84
+ the relevant existing constraints and decisions from the response before
85
+ planning a behavior change; a search receipt is not comprehension.
86
+
36
87
  ## Discovery to Validation Sequence
37
88
 
38
89
  The canonical workflow for any KB operation follows this pattern:
39
90
 
40
- 1. **Discover**: `kb_search` with focused probes
91
+ 1. **Discover**: `kb_search` with focused probes; pick the mode above
41
92
  2. **Confirm**: `kb_query` for exact IDs and state
42
93
  3. **Inspect**: `kb_status` when freshness matters
43
94
  4. **Decompose**: `kb_semantic_advisor` on the complete normative prose; verify or supply every atomic clause
@@ -362,7 +362,14 @@ export function launchKibiMcp(
362
362
  [projectLocal.binPath, ...childArgs],
363
363
  {
364
364
  cwd: workspaceRoot,
365
- env: { ...env, KIBI_WORKSPACE: workspaceRoot },
365
+ env: {
366
+ ...env,
367
+ KIBI_WORKSPACE: workspaceRoot,
368
+ // Identify the host on usage rows. This never enables telemetry;
369
+ // KIBI_DIAGNOSTIC_MODE stays the operator's explicit opt-in and is
370
+ // passed through untouched.
371
+ KIBI_MCP_HOST: "cursor",
372
+ },
366
373
  stdio: ["inherit", "inherit", "inherit"],
367
374
  },
368
375
  );
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kibi-cursor",
3
3
  "displayName": "Kibi",
4
- "version": "2.0.0",
4
+ "version": "2.1.0",
5
5
  "description": "Optional Cursor adapter for Kibi. Requires SWI-Prolog 9+ and project-local kibi-cli, kibi-mcp, and kibi-core before the bundled MCP server can start.",
6
6
  "license": "AGPL-3.0-or-later",
7
7
  "author": {
@@ -362,7 +362,14 @@ export function launchKibiMcp(
362
362
  [projectLocal.binPath, ...childArgs],
363
363
  {
364
364
  cwd: workspaceRoot,
365
- env: { ...env, KIBI_WORKSPACE: workspaceRoot },
365
+ env: {
366
+ ...env,
367
+ KIBI_WORKSPACE: workspaceRoot,
368
+ // Identify the host on usage rows. This never enables telemetry;
369
+ // KIBI_DIAGNOSTIC_MODE stays the operator's explicit opt-in and is
370
+ // passed through untouched.
371
+ KIBI_MCP_HOST: "cursor",
372
+ },
366
373
  stdio: ["inherit", "inherit", "inherit"],
367
374
  },
368
375
  );
@@ -5,6 +5,17 @@ export type GuidanceContext = {
5
5
  readonly hasKibi: boolean;
6
6
  readonly mcpState: McpState;
7
7
  readonly workspaceTrusted: boolean;
8
+ /** Requirements the edited file already owns, when the manifest knows them. */
9
+ readonly linkedRequirementIds?: readonly string[];
8
10
  };
9
11
  export declare function readGuidance(filePath: string, context: GuidanceContext): string | undefined;
12
+ /**
13
+ * Guidance emitted before an edit is written.
14
+ *
15
+ * The post-edit and stop messages can only ask for repair once the code is
16
+ * already changed. This is the one point where retrieval can still inform the
17
+ * change, so it names the requirements the file already implements and asks
18
+ * for them to be read before the edit rather than reconciled after it.
19
+ */
20
+ export declare function preEditGuidance(filePath: string, context: GuidanceContext): string | undefined;
10
21
  export declare function writeGuidance(filePath: string, context: GuidanceContext): string | undefined;
package/dist/guidance.js CHANGED
@@ -18,6 +18,40 @@ export function readGuidance(filePath, context) {
18
18
  const advisory = interfaceAdvisory(context.mcpState, context.workspaceTrusted);
19
19
  return advisory ? [advisory, ...guidance].join("\n") : guidance.join("\n");
20
20
  }
21
+ /**
22
+ * Guidance emitted before an edit is written.
23
+ *
24
+ * The post-edit and stop messages can only ask for repair once the code is
25
+ * already changed. This is the one point where retrieval can still inform the
26
+ * change, so it names the requirements the file already implements and asks
27
+ * for them to be read before the edit rather than reconciled after it.
28
+ */
29
+ export function preEditGuidance(filePath, context) {
30
+ if (!context.hasKibi) {
31
+ return undefined;
32
+ }
33
+ const relativePath = toRepoRelativePath(filePath, context.cwd);
34
+ if (!isMeaningfulTrackedPath(relativePath)) {
35
+ return undefined;
36
+ }
37
+ if (isDocumentationTrackedPath(relativePath)) {
38
+ return undefined;
39
+ }
40
+ const linkedRequirements = context.linkedRequirementIds ?? [];
41
+ const guidance = linkedRequirements.length > 0
42
+ ? [
43
+ `Kibi pre-edit guidance: ${relativePath} already implements ${linkedRequirements.join(", ")}.`,
44
+ `Read those requirements with kb_query before changing behavior here, and widen with kb_query({sourceFile:"${relativePath}"}) for scenarios and tests.`,
45
+ "If the change contradicts an existing requirement, resolve that in Kibi before writing the edit.",
46
+ ]
47
+ : [
48
+ `Kibi pre-edit guidance: ${relativePath} has no linked requirement in the symbol manifest.`,
49
+ `Discover existing constraints with kb_search, then kb_query({sourceFile:"${relativePath}"}), before changing behavior here.`,
50
+ "Record the requirement this change serves rather than leaving the symbol unowned.",
51
+ ];
52
+ const advisory = interfaceAdvisory(context.mcpState, context.workspaceTrusted);
53
+ return advisory ? [advisory, ...guidance].join("\n") : guidance.join("\n");
54
+ }
21
55
  export function writeGuidance(filePath, context) {
22
56
  if (!context.hasKibi) {
23
57
  return undefined;
@@ -35,12 +69,12 @@ export function writeGuidance(filePath, context) {
35
69
  const advisory = interfaceAdvisory(context.mcpState, context.workspaceTrusted);
36
70
  return advisory ? [advisory, ...guidance].join("\n") : guidance.join("\n");
37
71
  }
72
+ // Retrieval is asked for before the edit; this message stays scoped to the
73
+ // impact review that only becomes possible once the change exists.
38
74
  const guidance = [
39
- "Kibi write guidance: use the selected MCP or CLI JSON route to link production symbols to requirements.",
40
- `After editing, run kb_check({sourceFiles:["${relativePath}"], includeImpactDiagnostics:true, includeWorkingTreeDiff:true}) for symbol granularity and semantic review of linked requirements/tests.`,
41
- `After editing, resolve freshness with kb_search/kb_query for sourceFile="${relativePath}".`,
42
- "Prefer symbol manifest + executable_for or // implements REQ-xxx for traceability.",
43
- "Do not read or edit `.kb/` files directly. Query before mutate; run kb_upsert sequentially and kb_check before completion.",
75
+ `Kibi impact review: run kb_check({sourceFiles:["${relativePath}"], includeImpactDiagnostics:true, includeWorkingTreeDiff:true}) while this edit is fresh.`,
76
+ "Check symbol granularity and whether linked requirements, scenarios, and tests still cover the changed behavior.",
77
+ "Prefer symbol manifest + executable_for or // implements REQ-<area>-<behavior> for traceability.",
44
78
  ];
45
79
  const advisory = interfaceAdvisory(context.mcpState, context.workspaceTrusted);
46
80
  return advisory ? [advisory, ...guidance].join("\n") : guidance.join("\n");
@@ -1,4 +1,10 @@
1
+ // rationale: parseHookInput degrades every non-record to { event: "" };
2
+ // dropping the typeof check still yields the same parse for all inputs.
3
+ // Stryker disable next-line ConditionalExpression
1
4
  function isRecord(value) {
5
+ // rationale: parseHookInput degrades every non-record to { event: "" };
6
+ // dropping the typeof check still yields the same parse for all inputs.
7
+ // Stryker disable next-line ConditionalExpression
2
8
  return typeof value === "object" && value !== null && !Array.isArray(value);
3
9
  }
4
10
  function readString(record, keys) {
@@ -25,9 +31,6 @@ function readStringArray(record, keys) {
25
31
  }
26
32
  function normalizeEventName(event) {
27
33
  const trimmed = event.trim();
28
- if (trimmed.length === 0) {
29
- return "";
30
- }
31
34
  return trimmed.charAt(0).toLowerCase() + trimmed.slice(1);
32
35
  }
33
36
  function parseStopStatus(value) {
@@ -92,7 +95,7 @@ export function parseHookInput(input) {
92
95
  export async function readStdin() {
93
96
  const chunks = [];
94
97
  for await (const chunk of process.stdin) {
95
- chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
98
+ chunks.push(Buffer.from(chunk));
96
99
  }
97
100
  return Buffer.concat(chunks).toString("utf8");
98
101
  }