kibi-cursor 0.2.0 → 0.2.2
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/.cursor-plugin/plugin.json +1 -1
- package/CHANGELOG.md +29 -0
- package/dist/.cursor-plugin/plugin.json +1 -1
- package/dist/hook-input.d.ts +1 -0
- package/dist/hook-input.js +20 -0
- package/dist/hook-runner.js +2 -2
- package/dist/hook-state.js +3 -1
- package/dist/kb-mcp-tools.js +5 -1
- package/dist/messages.d.ts +1 -1
- package/dist/messages.js +1 -1
- package/dist/skills/kibi-usage/SKILL.md +208 -15
- package/package.json +1 -1
- package/skills/kibi-usage/SKILL.md +208 -15
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kibi-cursor",
|
|
3
3
|
"displayName": "Kibi",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.2",
|
|
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,34 @@
|
|
|
1
1
|
# kibi-cursor
|
|
2
2
|
|
|
3
|
+
## 0.2.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Kibi now gives agents clearer guidance for the diagnostics flow, so the release notes should reflect that the bundled usage text and MCP logging story were tightened together.
|
|
8
|
+
|
|
9
|
+
This update also keeps the package mirrors aligned where applicable, which helps downstream plugin consumers stay in sync with the canonical guidance.
|
|
10
|
+
|
|
11
|
+
- Hardened bundled skill guidance for kibi usage.
|
|
12
|
+
- Improved MCP diagnostic logging shape and validation hints.
|
|
13
|
+
- Synced packaged skill copies where they are shipped with the release.
|
|
14
|
+
|
|
15
|
+
## 0.2.1
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- 5d2975a: Cursor stop hooks no longer inject a long multi-line Kibi freshness reminder after every agent response. Follow-ups are now one line, and most sessions stay silent.
|
|
20
|
+
|
|
21
|
+
- Track `kb_upsert`, `kb_delete`, and `kb_check` MCP usage during the session.
|
|
22
|
+
- Emit no stop follow-up when nothing KB-relevant changed, or when `kb_check` already ran after edits.
|
|
23
|
+
- Emit a short summary (`Kibi KB updated (kb_upsert).`) after KB mutations, or a single-line sync nudge when source files changed without KB activity.
|
|
24
|
+
- Fix publish workflow to build and pack `kibi-cursor` tarballs before npm publish.
|
|
25
|
+
|
|
26
|
+
- Cursor sessions now use Cursor's documented workspace root payload when deciding whether Kibi is already configured. This prevents the plugin from telling agents that Kibi needs bootstrapping just because the hook process is running from the plugin install directory instead of the actual workspace. The bootstrap reminder now names the missing `.kb/config.json` condition directly instead of implying MCP is unavailable.
|
|
27
|
+
|
|
28
|
+
- Parse `workspace_roots` from Cursor hook payloads and prefer the first workspace root for Kibi config detection.
|
|
29
|
+
- Add a regression test covering `sessionStart` without `cwd` when `workspace_roots` points at a configured workspace.
|
|
30
|
+
- Reword the bootstrap reminder to describe a missing workspace config rather than generic initialization failure.
|
|
31
|
+
|
|
3
32
|
## 0.2.0
|
|
4
33
|
|
|
5
34
|
### Minor Changes
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kibi-cursor",
|
|
3
3
|
"displayName": "Kibi",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.2",
|
|
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/dist/hook-input.d.ts
CHANGED
package/dist/hook-input.js
CHANGED
|
@@ -10,6 +10,19 @@ function readString(record, keys) {
|
|
|
10
10
|
}
|
|
11
11
|
return undefined;
|
|
12
12
|
}
|
|
13
|
+
function readStringArray(record, keys) {
|
|
14
|
+
for (const key of keys) {
|
|
15
|
+
const value = record[key];
|
|
16
|
+
if (!Array.isArray(value)) {
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
const strings = value.filter((item) => typeof item === "string" && item.length > 0);
|
|
20
|
+
if (strings.length > 0) {
|
|
21
|
+
return strings;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
13
26
|
function normalizeEventName(event) {
|
|
14
27
|
const trimmed = event.trim();
|
|
15
28
|
if (trimmed.length === 0) {
|
|
@@ -34,6 +47,10 @@ export function parseHookInput(input) {
|
|
|
34
47
|
"current_working_directory",
|
|
35
48
|
"workspace",
|
|
36
49
|
]);
|
|
50
|
+
const workspaceRoots = readStringArray(input, [
|
|
51
|
+
"workspace_roots",
|
|
52
|
+
"workspaceRoots",
|
|
53
|
+
]);
|
|
37
54
|
const toolName = readString(input, ["toolName", "tool_name", "tool"]);
|
|
38
55
|
const toolInput = input.toolInput ?? input.tool_input ?? input.input;
|
|
39
56
|
const conversationId = readString(input, [
|
|
@@ -45,6 +62,9 @@ export function parseHookInput(input) {
|
|
|
45
62
|
if (cwd !== undefined) {
|
|
46
63
|
parsed.cwd = cwd;
|
|
47
64
|
}
|
|
65
|
+
if (workspaceRoots !== undefined) {
|
|
66
|
+
parsed.workspaceRoots = workspaceRoots;
|
|
67
|
+
}
|
|
48
68
|
if (toolName !== undefined) {
|
|
49
69
|
parsed.toolName = toolName;
|
|
50
70
|
}
|
package/dist/hook-runner.js
CHANGED
|
@@ -5,8 +5,8 @@ import path from "node:path";
|
|
|
5
5
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
6
6
|
import { readGuidance, writeGuidance } from "./guidance.js";
|
|
7
7
|
import { parseHookInput, parseStdinJson, readStdin } from "./hook-input.js";
|
|
8
|
-
import { extractKbMcpToolName } from "./kb-mcp-tools.js";
|
|
9
8
|
import { addDirtyPaths, clearSessionHookState, hasGuidedPath, loadHookState, recordKbMcpTool, rememberGuidedPath, resolveStateDir, } from "./hook-state.js";
|
|
9
|
+
import { extractKbMcpToolName } from "./kb-mcp-tools.js";
|
|
10
10
|
import { BOOTSTRAP_REMINDER, DIRECT_KB_EDIT_WARNING, stopFollowupMessage, } from "./messages.js";
|
|
11
11
|
import { extractExplicitPathFields, isDirectKbPath, isMeaningfulTrackedPath, toRepoRelativePath, } from "./path-policy.js";
|
|
12
12
|
const editableTools = new Set([
|
|
@@ -33,7 +33,7 @@ function isReadLikeTool(toolName) {
|
|
|
33
33
|
return toolName === undefined || readTools.has(toolName);
|
|
34
34
|
}
|
|
35
35
|
function resolveWorkspaceRoot(input) {
|
|
36
|
-
return input.cwd ?? process.cwd();
|
|
36
|
+
return input.workspaceRoots?.[0] ?? input.cwd ?? process.cwd();
|
|
37
37
|
}
|
|
38
38
|
function resolvePrimaryPath(input) {
|
|
39
39
|
if (input.filePath) {
|
package/dist/hook-state.js
CHANGED
|
@@ -231,7 +231,9 @@ export function recordKbMcpTool(stateDir, toolName) {
|
|
|
231
231
|
if (normalized === "kb_upsert" || normalized === "kb_delete") {
|
|
232
232
|
return {
|
|
233
233
|
...state,
|
|
234
|
-
kbMutationTools: mergeStringPaths(state.kbMutationTools, [
|
|
234
|
+
kbMutationTools: mergeStringPaths(state.kbMutationTools, [
|
|
235
|
+
normalized,
|
|
236
|
+
]).slice(-maxKbMutationTools),
|
|
235
237
|
};
|
|
236
238
|
}
|
|
237
239
|
return state;
|
package/dist/kb-mcp-tools.js
CHANGED
|
@@ -27,7 +27,11 @@ export function extractKbMcpToolName(toolName, toolInput) {
|
|
|
27
27
|
}
|
|
28
28
|
const nestedArgs = toolInput.arguments ?? toolInput.args;
|
|
29
29
|
if (isRecord(nestedArgs)) {
|
|
30
|
-
const nestedTool = readString(nestedArgs, [
|
|
30
|
+
const nestedTool = readString(nestedArgs, [
|
|
31
|
+
"toolName",
|
|
32
|
+
"tool_name",
|
|
33
|
+
"name",
|
|
34
|
+
]);
|
|
31
35
|
if (nestedTool?.startsWith("kb_")) {
|
|
32
36
|
return nestedTool;
|
|
33
37
|
}
|
package/dist/messages.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { HookState } from "./hook-state.js";
|
|
2
|
-
export declare const BOOTSTRAP_REMINDER = "Kibi
|
|
2
|
+
export declare const BOOTSTRAP_REMINDER = "Kibi config was not found at the Cursor workspace root. Use the Kibi MCP /init-kibi workflow to bootstrap project memory before relying on KB lookups; do not edit .kb/ files directly.";
|
|
3
3
|
export declare const DIRECT_KB_EDIT_WARNING = "Avoid direct edits to .kb/. Use Kibi MCP tools for KB discovery and mutations so project memory stays valid.";
|
|
4
4
|
export declare function stopFollowupMessage(state: HookState): string | undefined;
|
|
5
5
|
/** @deprecated Use stopFollowupMessage */
|
package/dist/messages.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isKbFreshnessRelevantPath } from "./path-policy.js";
|
|
2
|
-
export const BOOTSTRAP_REMINDER = "Kibi
|
|
2
|
+
export const BOOTSTRAP_REMINDER = "Kibi config was not found at the Cursor workspace root. Use the Kibi MCP /init-kibi workflow to bootstrap project memory before relying on KB lookups; do not edit .kb/ files directly.";
|
|
3
3
|
export const DIRECT_KB_EDIT_WARNING = "Avoid direct edits to .kb/. Use Kibi MCP tools for KB discovery and mutations so project memory stays valid.";
|
|
4
4
|
export function stopFollowupMessage(state) {
|
|
5
5
|
if (state.kbMutationTools.length > 0) {
|
|
@@ -1,23 +1,216 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
id: kibi-usage
|
|
3
|
+
name: Kibi Usage
|
|
4
|
+
description: Guides agents to use Kibi MCP, facts, relationships, and validation correctly
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
kibiCompatibility: ">=0.11.0"
|
|
7
|
+
tags:
|
|
8
|
+
- kibi
|
|
9
|
+
- mcp
|
|
10
|
+
- knowledge-base
|
|
11
|
+
- traceability
|
|
12
|
+
- agent-guidance
|
|
13
|
+
resources:
|
|
14
|
+
- resources/relationship-directions.md
|
|
15
|
+
- resources/fact-lanes.md
|
|
16
|
+
- resources/workflows.md
|
|
4
17
|
---
|
|
5
18
|
|
|
6
|
-
|
|
19
|
+
# Kibi Usage
|
|
7
20
|
|
|
8
|
-
|
|
21
|
+
Consult this skill before any Kibi knowledge base operation, on first interaction with a Kibi-enabled repo, after detecting stale or dirty KB status, and before performing mutations.
|
|
9
22
|
|
|
10
|
-
## MCP
|
|
23
|
+
## MCP-Only Rules
|
|
11
24
|
|
|
12
|
-
|
|
13
|
-
- Move to `kb_query` for exact entity retrieval by `id` or `type`.
|
|
14
|
-
- Use `kb_status` when context is stale or branch linkage is unclear.
|
|
15
|
-
- Use curated reports only when the question needs them: `kb_find_gaps`, `kb_coverage`, or `kb_graph`.
|
|
16
|
-
- Mutate only through `kb_upsert` or `kb_delete`, then validate with `kb_check`.
|
|
25
|
+
Interact with the knowledge base exclusively through MCP tools. Do not read or edit files inside `.kb/` directly. Do not run any `kibi` CLI commands from the agent session. The MCP surface is the only sanctioned interface for agents.
|
|
17
26
|
|
|
18
|
-
|
|
27
|
+
### Tool Name Prefixes
|
|
19
28
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
29
|
+
Kibi's canonical MCP names are `kb_search`, `kb_query`, `kb_upsert`, `kb_check`, and related `kb_*` tools. Some hosts add a server prefix when exposing tools to agents. In OpenCode, use the visible `kibi_kb_search`, `kibi_kb_query`, `kibi_kb_upsert`, and `kibi_kb_check` names when exact tool identifiers are required; they map to the same canonical MCP names.
|
|
30
|
+
|
|
31
|
+
## Discovery-First Workflow
|
|
32
|
+
|
|
33
|
+
Always discover before you mutate. Start with `kb_search` for exploratory discovery across metadata and markdown body text. Split broad queries into 1-3 focused probes. Review top hits for relevance before concluding the KB lacks knowledge.
|
|
34
|
+
|
|
35
|
+
Follow up with `kb_query` for exact lookups by `id`, `type`, `tags`, or `sourceFile`. Call `kb_status` to inspect branch attachment and freshness when stale context would affect decisions. Only after discovery and confirmation should you mutate.
|
|
36
|
+
|
|
37
|
+
## Relationship Directions
|
|
38
|
+
|
|
39
|
+
Relationship direction is fixed and semantic. Getting it wrong breaks traceability queries and validation.
|
|
40
|
+
|
|
41
|
+
| Relationship | Direction | Meaning |
|
|
42
|
+
|-------------|-----------|---------|
|
|
43
|
+
| `implements` | symbol -> req | Symbol owns or implements requirement behavior |
|
|
44
|
+
| `specified_by` | req -> scenario | Requirement is specified by a scenario |
|
|
45
|
+
| `verified_by` | req/scenario -> test | Requirement or scenario is verified by a test |
|
|
46
|
+
| `validates` | test -> req/scenario | Test validates a requirement or scenario |
|
|
47
|
+
| `executable_for` | symbol -> test | Symbol is executable test code for a test entity |
|
|
48
|
+
| `constrains` | req -> fact(subject) | Requirement constrains a domain fact |
|
|
49
|
+
| `requires_property` | req -> fact(property_value) | Requirement requires a property value |
|
|
50
|
+
| `supersedes` | old-req -> new-req | Old requirement is replaced by new requirement |
|
|
51
|
+
| `covered_by` | symbol -> test | Production symbol has coverage evidence from a test |
|
|
52
|
+
|
|
53
|
+
See `resources/relationship-directions.md` for detailed payload examples.
|
|
54
|
+
|
|
55
|
+
## Symbol-First Traceability
|
|
56
|
+
|
|
57
|
+
Trace code through `symbol` entities, not inline legacy comments. Do not use legacy `// implements REQ-xxx` comments as the primary marker for new or modified code. If a symbol is new or its requirement ownership changes, create or update the `symbol` entity and add an `implements` relationship from the symbol to the requirement.
|
|
58
|
+
|
|
59
|
+
Use comments only as a temporary backward-compatibility fallback when the symbol manifest cannot be updated in the same task. Prefer durable symbol coordinates in `documentation/symbols.yaml` and `documentation/symbol-coordinates.yaml`, then link those symbols through MCP relationships.
|
|
60
|
+
|
|
61
|
+
```yaml
|
|
62
|
+
# Preferred traceability model
|
|
63
|
+
symbol:
|
|
64
|
+
id: SYM-admin-billing-policy
|
|
65
|
+
title: Admin billing policy check
|
|
66
|
+
status: active
|
|
67
|
+
relationships:
|
|
68
|
+
- type: implements
|
|
69
|
+
from: SYM-admin-billing-policy
|
|
70
|
+
to: REQ-ADMIN-BILLING-POLICY
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Strict Fact Lane
|
|
74
|
+
|
|
75
|
+
Normative requirements that must participate in contradiction blocking use the strict fact lane. Create a `fact_kind: subject` fact and link it from the requirement via `constrains`. Create a `fact_kind: property_value` fact and link it via `requires_property`.
|
|
76
|
+
|
|
77
|
+
```yaml
|
|
78
|
+
# Fact entity
|
|
79
|
+
id: FACT-USER-ROLE
|
|
80
|
+
title: User Role Assignment
|
|
81
|
+
status: active
|
|
82
|
+
fact_kind: subject
|
|
83
|
+
subject_key: user.role_assignment
|
|
84
|
+
|
|
85
|
+
# Requirement entity
|
|
86
|
+
id: REQ-019
|
|
87
|
+
title: Users can have up to 3 roles
|
|
88
|
+
status: open
|
|
89
|
+
relationships:
|
|
90
|
+
- type: constrains
|
|
91
|
+
from: REQ-019
|
|
92
|
+
to: FACT-USER-ROLE
|
|
93
|
+
- type: requires_property
|
|
94
|
+
from: REQ-019
|
|
95
|
+
to: FACT-LIMIT-3
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
See `resources/fact-lanes.md` for the full strict vs observation lane comparison.
|
|
99
|
+
|
|
100
|
+
### Granular fact examples for coherence checks
|
|
101
|
+
|
|
102
|
+
Model one semantic claim per strict `property_value` fact. Reusing the same `subject_key` and `property_key` lets `domain-contradictions` compare requirements mechanically.
|
|
103
|
+
|
|
104
|
+
Incoherent role-set example: `REQ-ROLE-SET-2` says the allowed user roles are exactly `[user, admin]`, while `REQ-ROLE-SET-3` says the same property is exactly `[user, admin, superadmin]`. Both constrain `FACT-USER-ROLES` and require different values for `user.roles.allowed_set`, so they cannot both be current.
|
|
105
|
+
|
|
106
|
+
```yaml
|
|
107
|
+
subject:
|
|
108
|
+
id: FACT-USER-ROLES
|
|
109
|
+
fact_kind: subject
|
|
110
|
+
subject_key: user.roles
|
|
111
|
+
|
|
112
|
+
property_values:
|
|
113
|
+
- id: FACT-USER-ROLES-ALLOWED-2
|
|
114
|
+
fact_kind: property_value
|
|
115
|
+
subject_key: user.roles
|
|
116
|
+
property_key: user.roles.allowed_set
|
|
117
|
+
operator: eq
|
|
118
|
+
value_type: list
|
|
119
|
+
value_json: '["user", "admin"]'
|
|
120
|
+
- id: FACT-USER-ROLES-ALLOWED-3
|
|
121
|
+
fact_kind: property_value
|
|
122
|
+
subject_key: user.roles
|
|
123
|
+
property_key: user.roles.allowed_set
|
|
124
|
+
operator: eq
|
|
125
|
+
value_type: list
|
|
126
|
+
value_json: '["user", "admin", "superadmin"]'
|
|
127
|
+
|
|
128
|
+
requirements:
|
|
129
|
+
- id: REQ-ROLE-SET-2
|
|
130
|
+
relationships:
|
|
131
|
+
- { type: constrains, from: REQ-ROLE-SET-2, to: FACT-USER-ROLES }
|
|
132
|
+
- { type: requires_property, from: REQ-ROLE-SET-2, to: FACT-USER-ROLES-ALLOWED-2 }
|
|
133
|
+
- id: REQ-ROLE-SET-3
|
|
134
|
+
relationships:
|
|
135
|
+
- { type: constrains, from: REQ-ROLE-SET-3, to: FACT-USER-ROLES }
|
|
136
|
+
- { type: requires_property, from: REQ-ROLE-SET-3, to: FACT-USER-ROLES-ALLOWED-3 }
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Incoherent permission example: `REQ-ADMIN-CAN-MANAGE-BILLING` says `admin` can manage billing, while `REQ-ONLY-SUPERADMIN-MANAGES-BILLING` says the only allowed actor is `superadmin`. Model both against `billing.manage.allowed_actor` with `operator: eq` so the conflict is explicit.
|
|
140
|
+
|
|
141
|
+
```yaml
|
|
142
|
+
property_values:
|
|
143
|
+
- id: FACT-BILLING-MANAGE-ACTOR-ADMIN
|
|
144
|
+
fact_kind: property_value
|
|
145
|
+
subject_key: billing.manage
|
|
146
|
+
property_key: billing.manage.allowed_actor
|
|
147
|
+
operator: eq
|
|
148
|
+
value_type: string
|
|
149
|
+
value_string: admin
|
|
150
|
+
- id: FACT-BILLING-MANAGE-ACTOR-SUPERADMIN
|
|
151
|
+
fact_kind: property_value
|
|
152
|
+
subject_key: billing.manage
|
|
153
|
+
property_key: billing.manage.allowed_actor
|
|
154
|
+
operator: eq
|
|
155
|
+
value_type: string
|
|
156
|
+
value_string: superadmin
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
If a new requirement intentionally changes a value, create a replacement requirement and link the old requirement to the new one with `supersedes` instead of leaving two current contradictory requirements.
|
|
160
|
+
|
|
161
|
+
## Fact vs Flag
|
|
162
|
+
|
|
163
|
+
Use `flag` for runtime or config gates only. Feature flags, kill-switches, and deferred capabilities are valid `flag` entities.
|
|
164
|
+
|
|
165
|
+
Bugs, incidents, and workarounds belong in `fact` entities with `fact_kind: observation` or `meta`. These fact kinds are excluded from contradiction inference, making them appropriate for non-blocking evidence.
|
|
166
|
+
|
|
167
|
+
Anti-example: do not create a `flag` named `BUG-123` to track a defect. Create a `fact` with `fact_kind: observation` instead.
|
|
168
|
+
|
|
169
|
+
## Create-Before-Link
|
|
170
|
+
|
|
171
|
+
Always confirm or create endpoint entities before linking them. Query target IDs with `kb_query` first. If an endpoint does not exist, create it with `kb_upsert` before creating the relationship. Creating relationships to non-existent entities produces dangling references that `kb_check` will flag.
|
|
172
|
+
|
|
173
|
+
For `kb_upsert`, keep relationship rows anchored to the entity you are upserting: each row's `from` must equal the upserted entity ID. If you need a `SYM -> REQ` link, upsert the symbol endpoint first, then link that symbol to the requirement.
|
|
174
|
+
|
|
175
|
+
Keep symbol payloads minimal: include only the fields needed to identify the symbol, its status, and its source traceability. Put extra prose, examples, or audit notes in docs or evidence files instead of custom `kb_upsert.properties`; strict `kb_upsert.properties` rejects unknown fields.
|
|
176
|
+
|
|
177
|
+
When a generic `Query failed` appears, do not keep retrying the same payload. First call `kb_validate_upsert`, query or create the missing endpoints, reduce the payload to the minimum required fields, and retry once. If it still fails, report the blocker instead of looping.
|
|
178
|
+
|
|
179
|
+
## Sequential Upserts
|
|
180
|
+
|
|
181
|
+
Never fire `kb_upsert` calls in parallel. Execute them sequentially to avoid lock contention and ensure deterministic ordering. This is especially important when creating chains of related entities.
|
|
182
|
+
|
|
183
|
+
## Targeted and Final Checks
|
|
184
|
+
|
|
185
|
+
Run `kb_check` with specific rules during iteration for fast feedback. For example, use `rules: ["required-fields", "no-dangling-refs"]` after small changes. Run a full `kb_check` without rule filters before declaring work complete.
|
|
186
|
+
|
|
187
|
+
## Domain Contradictions and Evolution
|
|
188
|
+
|
|
189
|
+
The `domain-contradictions` rule detects conflicts between strict-lane facts linked to requirements. When a contradiction is found, the supported escape hatch is `supersedes`: create a new requirement that supersedes the old one, then link the new requirement to updated facts.
|
|
190
|
+
|
|
191
|
+
Use `kb_model_requirement` for automated strict-fact modeling. It generates the subject and property_value facts, links them via `constrains` and `requires_property`, and handles low-confidence downgrades to `observation` facts automatically.
|
|
192
|
+
|
|
193
|
+
## Stale or Dirty KB Handling
|
|
194
|
+
|
|
195
|
+
Call `kb_status` when you suspect the branch KB is stale or when switching context. Report freshness findings to the user rather than relying on outdated KB context. If `kb_status` indicates a schema migration is needed, ask the user or operator to handle it outside the agent session.
|
|
196
|
+
|
|
197
|
+
## Anti-Patterns and Remediation
|
|
198
|
+
|
|
199
|
+
| Anti-Pattern | Problem | Remediation |
|
|
200
|
+
|-------------|---------|-------------|
|
|
201
|
+
| Reversed relationship direction | Traceability queries break | Verify direction against the relationship table above |
|
|
202
|
+
| Legacy implements comments | Comments are not durable queryable symbols | Create or update a `symbol` entity and link it to the requirement |
|
|
203
|
+
| Bug-as-flag | `flag` misused for defect tracking | Use `fact` with `fact_kind: observation` or `meta` |
|
|
204
|
+
| Parallel upserts | Lock contention and nondeterminism | Execute `kb_upsert` calls sequentially |
|
|
205
|
+
| Embedded scenarios in reqs | Violates canonical traceability chain | Create separate `req`, `scen`, and `test` entities |
|
|
206
|
+
| Missing `kb_check` | Undetected dangling refs and violations | Run targeted checks during work, full check at completion |
|
|
207
|
+
| Tags as multi-ID lookup | Tags are metadata, not identifiers | Use `kb_query` with explicit `id` values |
|
|
208
|
+
| `relates_to` for strict modeling | Loses contradiction safety | Use `constrains` and `requires_property` instead |
|
|
209
|
+
| `status: implemented` on requirements | Not a valid lifecycle status | Use a valid status such as `closed`, add an `implemented` tag, and link evidence instead |
|
|
210
|
+
|
|
211
|
+
Before/after for reversed direction:
|
|
212
|
+
|
|
213
|
+
- Wrong: `relationships: [{ type: "implements", from: "REQ-001", to: "SYM-001" }]`
|
|
214
|
+
- Right: `relationships: [{ type: "implements", from: "SYM-001", to: "REQ-001" }]`
|
|
215
|
+
|
|
216
|
+
See `resources/workflows.md` for the golden-path discovery to validation sequence.
|
package/package.json
CHANGED
|
@@ -1,23 +1,216 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
id: kibi-usage
|
|
3
|
+
name: Kibi Usage
|
|
4
|
+
description: Guides agents to use Kibi MCP, facts, relationships, and validation correctly
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
kibiCompatibility: ">=0.11.0"
|
|
7
|
+
tags:
|
|
8
|
+
- kibi
|
|
9
|
+
- mcp
|
|
10
|
+
- knowledge-base
|
|
11
|
+
- traceability
|
|
12
|
+
- agent-guidance
|
|
13
|
+
resources:
|
|
14
|
+
- resources/relationship-directions.md
|
|
15
|
+
- resources/fact-lanes.md
|
|
16
|
+
- resources/workflows.md
|
|
4
17
|
---
|
|
5
18
|
|
|
6
|
-
|
|
19
|
+
# Kibi Usage
|
|
7
20
|
|
|
8
|
-
|
|
21
|
+
Consult this skill before any Kibi knowledge base operation, on first interaction with a Kibi-enabled repo, after detecting stale or dirty KB status, and before performing mutations.
|
|
9
22
|
|
|
10
|
-
## MCP
|
|
23
|
+
## MCP-Only Rules
|
|
11
24
|
|
|
12
|
-
|
|
13
|
-
- Move to `kb_query` for exact entity retrieval by `id` or `type`.
|
|
14
|
-
- Use `kb_status` when context is stale or branch linkage is unclear.
|
|
15
|
-
- Use curated reports only when the question needs them: `kb_find_gaps`, `kb_coverage`, or `kb_graph`.
|
|
16
|
-
- Mutate only through `kb_upsert` or `kb_delete`, then validate with `kb_check`.
|
|
25
|
+
Interact with the knowledge base exclusively through MCP tools. Do not read or edit files inside `.kb/` directly. Do not run any `kibi` CLI commands from the agent session. The MCP surface is the only sanctioned interface for agents.
|
|
17
26
|
|
|
18
|
-
|
|
27
|
+
### Tool Name Prefixes
|
|
19
28
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
29
|
+
Kibi's canonical MCP names are `kb_search`, `kb_query`, `kb_upsert`, `kb_check`, and related `kb_*` tools. Some hosts add a server prefix when exposing tools to agents. In OpenCode, use the visible `kibi_kb_search`, `kibi_kb_query`, `kibi_kb_upsert`, and `kibi_kb_check` names when exact tool identifiers are required; they map to the same canonical MCP names.
|
|
30
|
+
|
|
31
|
+
## Discovery-First Workflow
|
|
32
|
+
|
|
33
|
+
Always discover before you mutate. Start with `kb_search` for exploratory discovery across metadata and markdown body text. Split broad queries into 1-3 focused probes. Review top hits for relevance before concluding the KB lacks knowledge.
|
|
34
|
+
|
|
35
|
+
Follow up with `kb_query` for exact lookups by `id`, `type`, `tags`, or `sourceFile`. Call `kb_status` to inspect branch attachment and freshness when stale context would affect decisions. Only after discovery and confirmation should you mutate.
|
|
36
|
+
|
|
37
|
+
## Relationship Directions
|
|
38
|
+
|
|
39
|
+
Relationship direction is fixed and semantic. Getting it wrong breaks traceability queries and validation.
|
|
40
|
+
|
|
41
|
+
| Relationship | Direction | Meaning |
|
|
42
|
+
|-------------|-----------|---------|
|
|
43
|
+
| `implements` | symbol -> req | Symbol owns or implements requirement behavior |
|
|
44
|
+
| `specified_by` | req -> scenario | Requirement is specified by a scenario |
|
|
45
|
+
| `verified_by` | req/scenario -> test | Requirement or scenario is verified by a test |
|
|
46
|
+
| `validates` | test -> req/scenario | Test validates a requirement or scenario |
|
|
47
|
+
| `executable_for` | symbol -> test | Symbol is executable test code for a test entity |
|
|
48
|
+
| `constrains` | req -> fact(subject) | Requirement constrains a domain fact |
|
|
49
|
+
| `requires_property` | req -> fact(property_value) | Requirement requires a property value |
|
|
50
|
+
| `supersedes` | old-req -> new-req | Old requirement is replaced by new requirement |
|
|
51
|
+
| `covered_by` | symbol -> test | Production symbol has coverage evidence from a test |
|
|
52
|
+
|
|
53
|
+
See `resources/relationship-directions.md` for detailed payload examples.
|
|
54
|
+
|
|
55
|
+
## Symbol-First Traceability
|
|
56
|
+
|
|
57
|
+
Trace code through `symbol` entities, not inline legacy comments. Do not use legacy `// implements REQ-xxx` comments as the primary marker for new or modified code. If a symbol is new or its requirement ownership changes, create or update the `symbol` entity and add an `implements` relationship from the symbol to the requirement.
|
|
58
|
+
|
|
59
|
+
Use comments only as a temporary backward-compatibility fallback when the symbol manifest cannot be updated in the same task. Prefer durable symbol coordinates in `documentation/symbols.yaml` and `documentation/symbol-coordinates.yaml`, then link those symbols through MCP relationships.
|
|
60
|
+
|
|
61
|
+
```yaml
|
|
62
|
+
# Preferred traceability model
|
|
63
|
+
symbol:
|
|
64
|
+
id: SYM-admin-billing-policy
|
|
65
|
+
title: Admin billing policy check
|
|
66
|
+
status: active
|
|
67
|
+
relationships:
|
|
68
|
+
- type: implements
|
|
69
|
+
from: SYM-admin-billing-policy
|
|
70
|
+
to: REQ-ADMIN-BILLING-POLICY
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Strict Fact Lane
|
|
74
|
+
|
|
75
|
+
Normative requirements that must participate in contradiction blocking use the strict fact lane. Create a `fact_kind: subject` fact and link it from the requirement via `constrains`. Create a `fact_kind: property_value` fact and link it via `requires_property`.
|
|
76
|
+
|
|
77
|
+
```yaml
|
|
78
|
+
# Fact entity
|
|
79
|
+
id: FACT-USER-ROLE
|
|
80
|
+
title: User Role Assignment
|
|
81
|
+
status: active
|
|
82
|
+
fact_kind: subject
|
|
83
|
+
subject_key: user.role_assignment
|
|
84
|
+
|
|
85
|
+
# Requirement entity
|
|
86
|
+
id: REQ-019
|
|
87
|
+
title: Users can have up to 3 roles
|
|
88
|
+
status: open
|
|
89
|
+
relationships:
|
|
90
|
+
- type: constrains
|
|
91
|
+
from: REQ-019
|
|
92
|
+
to: FACT-USER-ROLE
|
|
93
|
+
- type: requires_property
|
|
94
|
+
from: REQ-019
|
|
95
|
+
to: FACT-LIMIT-3
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
See `resources/fact-lanes.md` for the full strict vs observation lane comparison.
|
|
99
|
+
|
|
100
|
+
### Granular fact examples for coherence checks
|
|
101
|
+
|
|
102
|
+
Model one semantic claim per strict `property_value` fact. Reusing the same `subject_key` and `property_key` lets `domain-contradictions` compare requirements mechanically.
|
|
103
|
+
|
|
104
|
+
Incoherent role-set example: `REQ-ROLE-SET-2` says the allowed user roles are exactly `[user, admin]`, while `REQ-ROLE-SET-3` says the same property is exactly `[user, admin, superadmin]`. Both constrain `FACT-USER-ROLES` and require different values for `user.roles.allowed_set`, so they cannot both be current.
|
|
105
|
+
|
|
106
|
+
```yaml
|
|
107
|
+
subject:
|
|
108
|
+
id: FACT-USER-ROLES
|
|
109
|
+
fact_kind: subject
|
|
110
|
+
subject_key: user.roles
|
|
111
|
+
|
|
112
|
+
property_values:
|
|
113
|
+
- id: FACT-USER-ROLES-ALLOWED-2
|
|
114
|
+
fact_kind: property_value
|
|
115
|
+
subject_key: user.roles
|
|
116
|
+
property_key: user.roles.allowed_set
|
|
117
|
+
operator: eq
|
|
118
|
+
value_type: list
|
|
119
|
+
value_json: '["user", "admin"]'
|
|
120
|
+
- id: FACT-USER-ROLES-ALLOWED-3
|
|
121
|
+
fact_kind: property_value
|
|
122
|
+
subject_key: user.roles
|
|
123
|
+
property_key: user.roles.allowed_set
|
|
124
|
+
operator: eq
|
|
125
|
+
value_type: list
|
|
126
|
+
value_json: '["user", "admin", "superadmin"]'
|
|
127
|
+
|
|
128
|
+
requirements:
|
|
129
|
+
- id: REQ-ROLE-SET-2
|
|
130
|
+
relationships:
|
|
131
|
+
- { type: constrains, from: REQ-ROLE-SET-2, to: FACT-USER-ROLES }
|
|
132
|
+
- { type: requires_property, from: REQ-ROLE-SET-2, to: FACT-USER-ROLES-ALLOWED-2 }
|
|
133
|
+
- id: REQ-ROLE-SET-3
|
|
134
|
+
relationships:
|
|
135
|
+
- { type: constrains, from: REQ-ROLE-SET-3, to: FACT-USER-ROLES }
|
|
136
|
+
- { type: requires_property, from: REQ-ROLE-SET-3, to: FACT-USER-ROLES-ALLOWED-3 }
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Incoherent permission example: `REQ-ADMIN-CAN-MANAGE-BILLING` says `admin` can manage billing, while `REQ-ONLY-SUPERADMIN-MANAGES-BILLING` says the only allowed actor is `superadmin`. Model both against `billing.manage.allowed_actor` with `operator: eq` so the conflict is explicit.
|
|
140
|
+
|
|
141
|
+
```yaml
|
|
142
|
+
property_values:
|
|
143
|
+
- id: FACT-BILLING-MANAGE-ACTOR-ADMIN
|
|
144
|
+
fact_kind: property_value
|
|
145
|
+
subject_key: billing.manage
|
|
146
|
+
property_key: billing.manage.allowed_actor
|
|
147
|
+
operator: eq
|
|
148
|
+
value_type: string
|
|
149
|
+
value_string: admin
|
|
150
|
+
- id: FACT-BILLING-MANAGE-ACTOR-SUPERADMIN
|
|
151
|
+
fact_kind: property_value
|
|
152
|
+
subject_key: billing.manage
|
|
153
|
+
property_key: billing.manage.allowed_actor
|
|
154
|
+
operator: eq
|
|
155
|
+
value_type: string
|
|
156
|
+
value_string: superadmin
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
If a new requirement intentionally changes a value, create a replacement requirement and link the old requirement to the new one with `supersedes` instead of leaving two current contradictory requirements.
|
|
160
|
+
|
|
161
|
+
## Fact vs Flag
|
|
162
|
+
|
|
163
|
+
Use `flag` for runtime or config gates only. Feature flags, kill-switches, and deferred capabilities are valid `flag` entities.
|
|
164
|
+
|
|
165
|
+
Bugs, incidents, and workarounds belong in `fact` entities with `fact_kind: observation` or `meta`. These fact kinds are excluded from contradiction inference, making them appropriate for non-blocking evidence.
|
|
166
|
+
|
|
167
|
+
Anti-example: do not create a `flag` named `BUG-123` to track a defect. Create a `fact` with `fact_kind: observation` instead.
|
|
168
|
+
|
|
169
|
+
## Create-Before-Link
|
|
170
|
+
|
|
171
|
+
Always confirm or create endpoint entities before linking them. Query target IDs with `kb_query` first. If an endpoint does not exist, create it with `kb_upsert` before creating the relationship. Creating relationships to non-existent entities produces dangling references that `kb_check` will flag.
|
|
172
|
+
|
|
173
|
+
For `kb_upsert`, keep relationship rows anchored to the entity you are upserting: each row's `from` must equal the upserted entity ID. If you need a `SYM -> REQ` link, upsert the symbol endpoint first, then link that symbol to the requirement.
|
|
174
|
+
|
|
175
|
+
Keep symbol payloads minimal: include only the fields needed to identify the symbol, its status, and its source traceability. Put extra prose, examples, or audit notes in docs or evidence files instead of custom `kb_upsert.properties`; strict `kb_upsert.properties` rejects unknown fields.
|
|
176
|
+
|
|
177
|
+
When a generic `Query failed` appears, do not keep retrying the same payload. First call `kb_validate_upsert`, query or create the missing endpoints, reduce the payload to the minimum required fields, and retry once. If it still fails, report the blocker instead of looping.
|
|
178
|
+
|
|
179
|
+
## Sequential Upserts
|
|
180
|
+
|
|
181
|
+
Never fire `kb_upsert` calls in parallel. Execute them sequentially to avoid lock contention and ensure deterministic ordering. This is especially important when creating chains of related entities.
|
|
182
|
+
|
|
183
|
+
## Targeted and Final Checks
|
|
184
|
+
|
|
185
|
+
Run `kb_check` with specific rules during iteration for fast feedback. For example, use `rules: ["required-fields", "no-dangling-refs"]` after small changes. Run a full `kb_check` without rule filters before declaring work complete.
|
|
186
|
+
|
|
187
|
+
## Domain Contradictions and Evolution
|
|
188
|
+
|
|
189
|
+
The `domain-contradictions` rule detects conflicts between strict-lane facts linked to requirements. When a contradiction is found, the supported escape hatch is `supersedes`: create a new requirement that supersedes the old one, then link the new requirement to updated facts.
|
|
190
|
+
|
|
191
|
+
Use `kb_model_requirement` for automated strict-fact modeling. It generates the subject and property_value facts, links them via `constrains` and `requires_property`, and handles low-confidence downgrades to `observation` facts automatically.
|
|
192
|
+
|
|
193
|
+
## Stale or Dirty KB Handling
|
|
194
|
+
|
|
195
|
+
Call `kb_status` when you suspect the branch KB is stale or when switching context. Report freshness findings to the user rather than relying on outdated KB context. If `kb_status` indicates a schema migration is needed, ask the user or operator to handle it outside the agent session.
|
|
196
|
+
|
|
197
|
+
## Anti-Patterns and Remediation
|
|
198
|
+
|
|
199
|
+
| Anti-Pattern | Problem | Remediation |
|
|
200
|
+
|-------------|---------|-------------|
|
|
201
|
+
| Reversed relationship direction | Traceability queries break | Verify direction against the relationship table above |
|
|
202
|
+
| Legacy implements comments | Comments are not durable queryable symbols | Create or update a `symbol` entity and link it to the requirement |
|
|
203
|
+
| Bug-as-flag | `flag` misused for defect tracking | Use `fact` with `fact_kind: observation` or `meta` |
|
|
204
|
+
| Parallel upserts | Lock contention and nondeterminism | Execute `kb_upsert` calls sequentially |
|
|
205
|
+
| Embedded scenarios in reqs | Violates canonical traceability chain | Create separate `req`, `scen`, and `test` entities |
|
|
206
|
+
| Missing `kb_check` | Undetected dangling refs and violations | Run targeted checks during work, full check at completion |
|
|
207
|
+
| Tags as multi-ID lookup | Tags are metadata, not identifiers | Use `kb_query` with explicit `id` values |
|
|
208
|
+
| `relates_to` for strict modeling | Loses contradiction safety | Use `constrains` and `requires_property` instead |
|
|
209
|
+
| `status: implemented` on requirements | Not a valid lifecycle status | Use a valid status such as `closed`, add an `implemented` tag, and link evidence instead |
|
|
210
|
+
|
|
211
|
+
Before/after for reversed direction:
|
|
212
|
+
|
|
213
|
+
- Wrong: `relationships: [{ type: "implements", from: "REQ-001", to: "SYM-001" }]`
|
|
214
|
+
- Right: `relationships: [{ type: "implements", from: "SYM-001", to: "REQ-001" }]`
|
|
215
|
+
|
|
216
|
+
See `resources/workflows.md` for the golden-path discovery to validation sequence.
|