kibi-cursor 0.2.1 → 0.3.1
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 +40 -0
- package/README.md +4 -4
- package/dist/.cursor-plugin/plugin.json +1 -1
- package/dist/guidance.js +1 -0
- package/dist/hook-runner.js +7 -4
- package/dist/hook-state.d.ts +6 -1
- package/dist/hook-state.js +20 -2
- package/dist/kb-mcp-tools.d.ts +6 -0
- package/dist/kb-mcp-tools.js +88 -0
- package/dist/messages.js +19 -1
- package/dist/path-policy.d.ts +1 -0
- package/dist/path-policy.js +18 -0
- package/dist/rules/kibi-traceability.mdc +2 -0
- package/dist/skills/kibi-traceability/SKILL.md +2 -0
- package/dist/skills/kibi-usage/SKILL.md +210 -15
- package/package.json +1 -1
- package/rules/kibi-traceability.mdc +2 -0
- package/skills/kibi-traceability/SKILL.md +2 -0
- package/skills/kibi-usage/SKILL.md +210 -15
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kibi-cursor",
|
|
3
3
|
"displayName": "Kibi",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.1",
|
|
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,45 @@
|
|
|
1
1
|
# kibi-cursor
|
|
2
2
|
|
|
3
|
+
## 0.3.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- f1db710: Kibi check outputs now have a stable advisory diagnostics lane for auditability review signals. Operators and MCP clients can receive `qualityDiagnostics` alongside hard `violations` without advisory-only findings changing pass/fail counts or exit behavior. Existing staged impact failures, including symbol granularity violations, remain blocking. Source impact analysis now also highlights overly broad symbols, indistinguishable symbol coordinates, and mixed-purpose component/class ownership as review-only guidance.
|
|
8
|
+
|
|
9
|
+
Technical summary:
|
|
10
|
+
|
|
11
|
+
- Add the public `QualityDiagnostic` type with `error`, `warning`, `review`, and `info` severities plus explicit `blocking` semantics.
|
|
12
|
+
- Preserve existing `violations`, `diagnostics`, and `impactDiagnostics` fields while adding MCP structured `qualityDiagnostics` output support.
|
|
13
|
+
- Preserve explicitly filtered MCP `kb_check` rule semantics so advisory full-KB quality scans only run for unfiltered checks or requested impact diagnostics.
|
|
14
|
+
- Clarify Codex and Cursor bundled agent guidance so targeted checks use explicit rules and final checks omit rules for full-KB `qualityDiagnostics` review.
|
|
15
|
+
- Add quality diagnostic text formatting and shared blocking helpers that treat `blocking: true` or `severity: "error"` as hard failures.
|
|
16
|
+
- Add non-blocking `multi_requirement_symbol_review`, `duplicate_symbol_coordinate_review`, and `component_mixed_purpose_review` impact diagnostics.
|
|
17
|
+
|
|
18
|
+
## 0.3.0
|
|
19
|
+
|
|
20
|
+
### Minor Changes
|
|
21
|
+
|
|
22
|
+
- Kibi now gives agents source-impact feedback while they are still editing, instead of waiting for the commit hook to be the first signal. Meaningful source edits can be checked through MCP with changed-file impact diagnostics, so agents see coarse symbol ownership, stale symbol evidence, and semantic-review prompts while the source context is fresh. OpenCode, Cursor, and Codex adapters now steer agents toward that MCP-first workflow and keep CLI/hooks as the later safety net.
|
|
23
|
+
|
|
24
|
+
Technical summary:
|
|
25
|
+
|
|
26
|
+
- Add reusable CLI changed-file impact diagnostics and export them for MCP consumption.
|
|
27
|
+
- Extend MCP `kb_check` with source-file impact options and structured impact output.
|
|
28
|
+
- Update OpenCode, Cursor, and Codex guidance/hooks to request impact-enabled `kb_check` after source edits.
|
|
29
|
+
- Document semantic-review diagnostics and class-member granularity expectations.
|
|
30
|
+
|
|
31
|
+
## 0.2.2
|
|
32
|
+
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- 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.
|
|
36
|
+
|
|
37
|
+
This update also keeps the package mirrors aligned where applicable, which helps downstream plugin consumers stay in sync with the canonical guidance.
|
|
38
|
+
|
|
39
|
+
- Hardened bundled skill guidance for kibi usage.
|
|
40
|
+
- Improved MCP diagnostic logging shape and validation hints.
|
|
41
|
+
- Synced packaged skill copies where they are shipped with the release.
|
|
42
|
+
|
|
3
43
|
## 0.2.1
|
|
4
44
|
|
|
5
45
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -96,22 +96,22 @@ Hooks are warning-only and never replace MCP/CLI behavior:
|
|
|
96
96
|
- **sessionStart**: bootstrap reminder when `.kb/config.json` is missing.
|
|
97
97
|
- **preToolUse**: warns on explicit direct `.kb/**` edits without blocking.
|
|
98
98
|
- **beforeReadFile** and **postToolUse (Read)**: inject source-linked lookup guidance once per path per session.
|
|
99
|
-
- **postToolUse (Write/Edit)**: inject traceability and freshness guidance once per path per session.
|
|
100
|
-
- **stop**: emits a single freshness follow-up when meaningful paths changed during the session.
|
|
99
|
+
- **postToolUse (Write/Edit)**: inject traceability and freshness guidance once per path per session, including `kb_check({sourceFiles:[...], includeImpactDiagnostics:true, includeWorkingTreeDiff:true})` for meaningful source edits.
|
|
100
|
+
- **stop**: emits a single freshness or impact-check follow-up when meaningful paths changed during the session.
|
|
101
101
|
|
|
102
102
|
### What the plugin does not do
|
|
103
103
|
|
|
104
104
|
Per the thin-adapter architecture, `kibi-cursor` does not:
|
|
105
105
|
|
|
106
106
|
- Own KB storage, parsing, or validation
|
|
107
|
-
- Run background `kibi sync` or `kibi check` (use git hooks and MCP tools)
|
|
107
|
+
- Run background `kibi sync` or CLI `kibi check` (use git hooks and MCP tools; for source edits, use impact-enabled MCP `kb_check` first)
|
|
108
108
|
- Block agent actions in advisory mode
|
|
109
109
|
|
|
110
110
|
## Architecture
|
|
111
111
|
|
|
112
112
|
`kibi-cursor` is a thin bridge layer:
|
|
113
113
|
|
|
114
|
-
- **Agent-visible guidance**: public MCP tools (`kb_search`, `kb_query`, `kb_upsert`, `kb_check`, etc.) and the `/init-kibi` command
|
|
114
|
+
- **Agent-visible guidance**: public MCP tools (`kb_search`, `kb_query`, `kb_upsert`, impact-enabled `kb_check`, etc.) and the `/init-kibi` command
|
|
115
115
|
- **Editor-specific value**: Cursor hooks for read/write reminders and session freshness follow-ups
|
|
116
116
|
- **Foundation**: `kibi-core`, `kibi-cli`, and `kibi-mcp` remain required for project-local operations
|
|
117
117
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kibi-cursor",
|
|
3
3
|
"displayName": "Kibi",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.1",
|
|
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/guidance.js
CHANGED
|
@@ -31,6 +31,7 @@ export function writeGuidance(filePath, cwd, hasKibi) {
|
|
|
31
31
|
}
|
|
32
32
|
return [
|
|
33
33
|
"Kibi write guidance: link production symbols to requirements.",
|
|
34
|
+
`After editing, run kb_check({sourceFiles:["${relativePath}"], includeImpactDiagnostics:true, includeWorkingTreeDiff:true}) for symbol granularity and semantic review of linked requirements/tests.`,
|
|
34
35
|
`After editing, resolve freshness with kb_search/kb_query for sourceFile="${relativePath}".`,
|
|
35
36
|
"Prefer symbol manifest + executable_for or // implements REQ-xxx for traceability.",
|
|
36
37
|
].join("\n");
|
package/dist/hook-runner.js
CHANGED
|
@@ -6,7 +6,7 @@ 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
8
|
import { addDirtyPaths, clearSessionHookState, hasGuidedPath, loadHookState, recordKbMcpTool, rememberGuidedPath, resolveStateDir, } from "./hook-state.js";
|
|
9
|
-
import {
|
|
9
|
+
import { extractKbMcpToolCall } 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([
|
|
@@ -86,9 +86,12 @@ export async function runHook(rawInput, environment = {}) {
|
|
|
86
86
|
};
|
|
87
87
|
}
|
|
88
88
|
case "postToolUse": {
|
|
89
|
-
const
|
|
90
|
-
if (
|
|
91
|
-
recordKbMcpTool(stateDir,
|
|
89
|
+
const kbToolCall = extractKbMcpToolCall(input.toolName, input.toolInput);
|
|
90
|
+
if (kbToolCall) {
|
|
91
|
+
recordKbMcpTool(stateDir, kbToolCall.toolName, {
|
|
92
|
+
impactCheckRun: kbToolCall.impactCheckRun,
|
|
93
|
+
sourceFiles: kbToolCall.sourceFiles,
|
|
94
|
+
});
|
|
92
95
|
}
|
|
93
96
|
const explicitPaths = extractExplicitPathFields(input.toolInput);
|
|
94
97
|
const dirtyPaths = explicitPaths
|
package/dist/hook-state.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ export type HookState = {
|
|
|
4
4
|
guidedWritePaths: string[];
|
|
5
5
|
kbMutationTools: string[];
|
|
6
6
|
kbCheckRun: boolean;
|
|
7
|
+
impactCheckRun: boolean;
|
|
8
|
+
impactCheckedPaths: string[];
|
|
7
9
|
};
|
|
8
10
|
export declare function resolveStateDir(pluginData: string | undefined, conversationId: string | undefined): string | undefined;
|
|
9
11
|
export declare function loadHookState(stateDir: string | undefined): HookState;
|
|
@@ -12,7 +14,10 @@ export declare function updateHookState(stateDir: string | undefined, updater: (
|
|
|
12
14
|
export declare function addDirtyPaths(stateDir: string | undefined, dirtyPaths: readonly string[]): HookState;
|
|
13
15
|
export declare function rememberGuidedPath(stateDir: string | undefined, kind: "read" | "write", guidedPath: string): HookState;
|
|
14
16
|
export declare function hasGuidedPath(state: HookState, kind: "read" | "write", guidedPath: string): boolean;
|
|
15
|
-
export declare function recordKbMcpTool(stateDir: string | undefined, toolName: string
|
|
17
|
+
export declare function recordKbMcpTool(stateDir: string | undefined, toolName: string, options?: {
|
|
18
|
+
impactCheckRun?: boolean;
|
|
19
|
+
sourceFiles?: readonly string[];
|
|
20
|
+
}): HookState;
|
|
16
21
|
export declare function clearSessionHookState(stateDir: string | undefined): HookState;
|
|
17
22
|
/** @deprecated Use clearSessionHookState */
|
|
18
23
|
export declare function clearDirtyPaths(stateDir: string | undefined): HookState;
|
package/dist/hook-state.js
CHANGED
|
@@ -44,6 +44,8 @@ function emptyHookState() {
|
|
|
44
44
|
guidedWritePaths: [],
|
|
45
45
|
kbMutationTools: [],
|
|
46
46
|
kbCheckRun: false,
|
|
47
|
+
impactCheckRun: false,
|
|
48
|
+
impactCheckedPaths: [],
|
|
47
49
|
};
|
|
48
50
|
}
|
|
49
51
|
function acquireLock(pluginData) {
|
|
@@ -129,12 +131,21 @@ function coerceHookState(value) {
|
|
|
129
131
|
.filter((entry) => entry.length > 0)
|
|
130
132
|
: [];
|
|
131
133
|
const kbCheckRun = value.kbCheckRun === true;
|
|
134
|
+
const impactCheckRun = value.impactCheckRun === true;
|
|
135
|
+
const impactCheckedPaths = Array.isArray(value.impactCheckedPaths)
|
|
136
|
+
? value.impactCheckedPaths
|
|
137
|
+
.filter((entry) => typeof entry === "string")
|
|
138
|
+
.map(normalizePath)
|
|
139
|
+
.filter((entry) => entry.length > 0)
|
|
140
|
+
: [];
|
|
132
141
|
return {
|
|
133
142
|
dirtyPaths: [...new Set(dirtyPaths)].slice(-maxDirtyPaths),
|
|
134
143
|
guidedReadPaths: [...new Set(guidedReadPaths)].slice(-maxGuidedPaths),
|
|
135
144
|
guidedWritePaths: [...new Set(guidedWritePaths)].slice(-maxGuidedPaths),
|
|
136
145
|
kbMutationTools: [...new Set(kbMutationTools)].slice(-maxKbMutationTools),
|
|
137
146
|
kbCheckRun,
|
|
147
|
+
impactCheckRun,
|
|
148
|
+
impactCheckedPaths: [...new Set(impactCheckedPaths)].slice(-maxGuidedPaths),
|
|
138
149
|
};
|
|
139
150
|
}
|
|
140
151
|
export function resolveStateDir(pluginData, conversationId) {
|
|
@@ -219,14 +230,21 @@ export function hasGuidedPath(state, kind, guidedPath) {
|
|
|
219
230
|
const bucket = kind === "read" ? state.guidedReadPaths : state.guidedWritePaths;
|
|
220
231
|
return bucket.includes(normalized);
|
|
221
232
|
}
|
|
222
|
-
export function recordKbMcpTool(stateDir, toolName) {
|
|
233
|
+
export function recordKbMcpTool(stateDir, toolName, options = {}) {
|
|
223
234
|
const normalized = toolName.trim();
|
|
224
235
|
if (normalized.length === 0) {
|
|
225
236
|
return loadHookState(stateDir);
|
|
226
237
|
}
|
|
227
238
|
return updateHookState(stateDir, (state) => {
|
|
228
239
|
if (normalized === "kb_check") {
|
|
229
|
-
return {
|
|
240
|
+
return {
|
|
241
|
+
...state,
|
|
242
|
+
kbCheckRun: true,
|
|
243
|
+
impactCheckRun: state.impactCheckRun || options.impactCheckRun === true,
|
|
244
|
+
impactCheckedPaths: options.impactCheckRun === true
|
|
245
|
+
? mergeStringPaths(state.impactCheckedPaths, options.sourceFiles ?? [])
|
|
246
|
+
: state.impactCheckedPaths,
|
|
247
|
+
};
|
|
230
248
|
}
|
|
231
249
|
if (normalized === "kb_upsert" || normalized === "kb_delete") {
|
|
232
250
|
return {
|
package/dist/kb-mcp-tools.d.ts
CHANGED
|
@@ -1 +1,7 @@
|
|
|
1
|
+
export type KbMcpToolCall = {
|
|
2
|
+
toolName: string;
|
|
3
|
+
impactCheckRun: boolean;
|
|
4
|
+
sourceFiles: string[];
|
|
5
|
+
};
|
|
6
|
+
export declare function extractKbMcpToolCall(toolName: string | undefined, toolInput: unknown): KbMcpToolCall | undefined;
|
|
1
7
|
export declare function extractKbMcpToolName(toolName: string | undefined, toolInput: unknown): string | undefined;
|
package/dist/kb-mcp-tools.js
CHANGED
|
@@ -11,7 +11,95 @@ function readString(record, keys) {
|
|
|
11
11
|
}
|
|
12
12
|
return undefined;
|
|
13
13
|
}
|
|
14
|
+
function readBoolean(record, keys) {
|
|
15
|
+
for (const key of keys) {
|
|
16
|
+
const value = record[key];
|
|
17
|
+
if (typeof value === "boolean") {
|
|
18
|
+
return value;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
function readStringArray(record, keys) {
|
|
24
|
+
for (const key of keys) {
|
|
25
|
+
const value = record[key];
|
|
26
|
+
if (!Array.isArray(value)) {
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
return value.filter((item) => typeof item === "string" && item.length > 0);
|
|
30
|
+
}
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
function readRecord(record, keys) {
|
|
34
|
+
for (const key of keys) {
|
|
35
|
+
const value = record[key];
|
|
36
|
+
if (isRecord(value)) {
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
export function extractKbMcpToolCall(toolName, toolInput) {
|
|
43
|
+
const directToolName = toolName?.trim();
|
|
44
|
+
let normalizedToolName = directToolName?.startsWith("kb_")
|
|
45
|
+
? directToolName
|
|
46
|
+
: undefined;
|
|
47
|
+
if (isRecord(toolInput)) {
|
|
48
|
+
normalizedToolName ??= readString(toolInput, [
|
|
49
|
+
"toolName",
|
|
50
|
+
"tool_name",
|
|
51
|
+
"name",
|
|
52
|
+
]);
|
|
53
|
+
const args = readRecord(toolInput, ["arguments", "args"]);
|
|
54
|
+
const payload = args ?? toolInput;
|
|
55
|
+
const includeImpactDiagnostics = readBoolean(payload, [
|
|
56
|
+
"includeImpactDiagnostics",
|
|
57
|
+
"include_impact_diagnostics",
|
|
58
|
+
]);
|
|
59
|
+
const includeWorkingTreeDiff = readBoolean(payload, [
|
|
60
|
+
"includeWorkingTreeDiff",
|
|
61
|
+
"include_working_tree_diff",
|
|
62
|
+
]);
|
|
63
|
+
const sourceFiles = readStringArray(payload, [
|
|
64
|
+
"sourceFiles",
|
|
65
|
+
"source_files",
|
|
66
|
+
]);
|
|
67
|
+
if (normalizedToolName?.startsWith("kb_")) {
|
|
68
|
+
return {
|
|
69
|
+
toolName: normalizedToolName,
|
|
70
|
+
impactCheckRun: normalizedToolName === "kb_check" &&
|
|
71
|
+
includeImpactDiagnostics === true &&
|
|
72
|
+
includeWorkingTreeDiff === true &&
|
|
73
|
+
sourceFiles.length > 0,
|
|
74
|
+
sourceFiles,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
const nestedArgs = toolInput.arguments ?? toolInput.args;
|
|
78
|
+
if (isRecord(nestedArgs)) {
|
|
79
|
+
const nestedTool = readString(nestedArgs, [
|
|
80
|
+
"toolName",
|
|
81
|
+
"tool_name",
|
|
82
|
+
"name",
|
|
83
|
+
]);
|
|
84
|
+
if (nestedTool?.startsWith("kb_")) {
|
|
85
|
+
return { toolName: nestedTool, impactCheckRun: false, sourceFiles: [] };
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (normalizedToolName?.startsWith("kb_")) {
|
|
90
|
+
return {
|
|
91
|
+
toolName: normalizedToolName,
|
|
92
|
+
impactCheckRun: false,
|
|
93
|
+
sourceFiles: [],
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
14
98
|
export function extractKbMcpToolName(toolName, toolInput) {
|
|
99
|
+
const toolCall = extractKbMcpToolCall(toolName, toolInput);
|
|
100
|
+
if (toolCall) {
|
|
101
|
+
return toolCall.toolName;
|
|
102
|
+
}
|
|
15
103
|
if (toolName) {
|
|
16
104
|
const normalized = toolName.trim();
|
|
17
105
|
if (normalized.startsWith("kb_")) {
|
package/dist/messages.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isKbFreshnessRelevantPath } from "./path-policy.js";
|
|
1
|
+
import { isKbFreshnessRelevantPath, isSourceImpactRelevantPath, } from "./path-policy.js";
|
|
2
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) {
|
|
@@ -6,6 +6,14 @@ export function stopFollowupMessage(state) {
|
|
|
6
6
|
const tools = [...new Set(state.kbMutationTools)];
|
|
7
7
|
return `Kibi KB updated (${tools.join(", ")}).`;
|
|
8
8
|
}
|
|
9
|
+
const sourceImpactPaths = state.dirtyPaths.filter(isSourceImpactRelevantPath);
|
|
10
|
+
const uncheckedSourcePaths = sourceImpactPaths.filter((sourcePath) => !state.impactCheckedPaths.includes(sourcePath));
|
|
11
|
+
if (uncheckedSourcePaths.length > 0 && !state.impactCheckRun) {
|
|
12
|
+
return impactCheckFollowup(uncheckedSourcePaths);
|
|
13
|
+
}
|
|
14
|
+
if (uncheckedSourcePaths.length > 0) {
|
|
15
|
+
return impactCheckFollowup(uncheckedSourcePaths);
|
|
16
|
+
}
|
|
9
17
|
const freshnessPaths = state.dirtyPaths.filter(isKbFreshnessRelevantPath);
|
|
10
18
|
if (freshnessPaths.length === 0 || state.kbCheckRun) {
|
|
11
19
|
return undefined;
|
|
@@ -14,6 +22,16 @@ export function stopFollowupMessage(state) {
|
|
|
14
22
|
const noun = fileCount === 1 ? "file" : "files";
|
|
15
23
|
return `Kibi: sync or record no-impact after ${fileCount} edited ${noun}.`;
|
|
16
24
|
}
|
|
25
|
+
function impactCheckFollowup(sourcePaths) {
|
|
26
|
+
const fileCount = sourcePaths.length;
|
|
27
|
+
const noun = fileCount === 1 ? "file" : "files";
|
|
28
|
+
const sourceFiles = JSON.stringify(sourcePaths.slice(0, 10));
|
|
29
|
+
return [
|
|
30
|
+
`Kibi: run impact-enabled kb_check after ${fileCount} edited source ${noun}.`,
|
|
31
|
+
`Use kb_check({sourceFiles:${sourceFiles}, includeImpactDiagnostics:true, includeWorkingTreeDiff:true}).`,
|
|
32
|
+
"Review symbol granularity and semantic review of linked requirements/tests before stopping.",
|
|
33
|
+
].join("\n");
|
|
34
|
+
}
|
|
17
35
|
/** @deprecated Use stopFollowupMessage */
|
|
18
36
|
export function freshnessReminder(dirtyPaths) {
|
|
19
37
|
const fileCount = dirtyPaths.length;
|
package/dist/path-policy.d.ts
CHANGED
|
@@ -3,5 +3,6 @@ export declare function isDirectKbPath(candidate: string): boolean;
|
|
|
3
3
|
export declare function isMeaningfulTrackedPath(candidate: string): boolean;
|
|
4
4
|
/** Paths whose edits should trigger a KB freshness stop follow-up. */
|
|
5
5
|
export declare function isKbFreshnessRelevantPath(candidate: string): boolean;
|
|
6
|
+
export declare function isSourceImpactRelevantPath(candidate: string): boolean;
|
|
6
7
|
export declare function isDocumentationTrackedPath(candidate: string): boolean;
|
|
7
8
|
export declare function toRepoRelativePath(candidate: string, cwd: string | undefined): string;
|
package/dist/path-policy.js
CHANGED
|
@@ -29,6 +29,7 @@ const sourceExtensions = new Set([
|
|
|
29
29
|
".mjs",
|
|
30
30
|
".mts",
|
|
31
31
|
".php",
|
|
32
|
+
".pl",
|
|
32
33
|
".py",
|
|
33
34
|
".rb",
|
|
34
35
|
".rs",
|
|
@@ -122,6 +123,23 @@ export function isKbFreshnessRelevantPath(candidate) {
|
|
|
122
123
|
segments[1] === "core" &&
|
|
123
124
|
segments[2] === "src");
|
|
124
125
|
}
|
|
126
|
+
export function isSourceImpactRelevantPath(candidate) {
|
|
127
|
+
const normalized = normalizePath(candidate);
|
|
128
|
+
const segments = pathSegments(normalized);
|
|
129
|
+
if (segments.includes(".kb") ||
|
|
130
|
+
segments.includes("dist") ||
|
|
131
|
+
segments.includes("tests") ||
|
|
132
|
+
segments.includes("test") ||
|
|
133
|
+
segments.includes("docs") ||
|
|
134
|
+
segments.includes("documentation")) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
const basename = segments.at(-1) ?? "";
|
|
138
|
+
const extension = basename.includes(".")
|
|
139
|
+
? `.${basename.split(".").at(-1) ?? ""}`
|
|
140
|
+
: "";
|
|
141
|
+
return segments.includes("src") && sourceExtensions.has(extension);
|
|
142
|
+
}
|
|
125
143
|
export function isDocumentationTrackedPath(candidate) {
|
|
126
144
|
const normalized = normalizePath(candidate);
|
|
127
145
|
const segments = pathSegments(normalized);
|
|
@@ -7,6 +7,8 @@ alwaysApply: false
|
|
|
7
7
|
|
|
8
8
|
Before changing production code, discover linked requirements with `kb_search` and `kb_query(sourceFile=...)`.
|
|
9
9
|
|
|
10
|
+
After meaningful source edits, run `kb_check({sourceFiles:[...], includeImpactDiagnostics:true, includeWorkingTreeDiff:true})` while the edit context is fresh. Review symbol granularity and whether linked requirements, scenarios, and tests still cover the changed behavior or UI copy.
|
|
11
|
+
|
|
10
12
|
Preserve the canonical chain `REQ-* -> SCEN-* -> TEST-*` when modeling behavior.
|
|
11
13
|
|
|
12
14
|
Prefer symbol manifest + `executable_for` for test/e2e code. Inline `// implements REQ-xxx` remains acceptable for quick code-only changes.
|
|
@@ -10,12 +10,14 @@ Validate and strengthen traceability before and after code changes.
|
|
|
10
10
|
## MCP workflow
|
|
11
11
|
|
|
12
12
|
- Locate requirements with `kb_search` and inspect exact details with `kb_query`.
|
|
13
|
+
- After meaningful source edits, run `kb_check({sourceFiles:[...], includeImpactDiagnostics:true, includeWorkingTreeDiff:true})` before deciding whether traceability is current.
|
|
13
14
|
- Apply updates with `kb_upsert` for requirements, scenarios, tests, or facts.
|
|
14
15
|
- Validate constraints and consistency with `kb_check`.
|
|
15
16
|
|
|
16
17
|
## Guidance
|
|
17
18
|
|
|
18
19
|
- Prefer source-linked relationships so symbols and files can be traced back cleanly.
|
|
20
|
+
- Treat `symbol_semantic_review_needed` as a prompt to inspect linked requirements/tests; Kibi reports graph links but does not prove prose semantics.
|
|
19
21
|
- Include `kb_query` and `kb_delete` only when explicit cleanups are required.
|
|
20
22
|
- Never directly edit `.kb/**`; all modeling and cleanup goes through MCP tools.
|
|
21
23
|
- Preserve the canonical chain `REQ-* -> SCEN-* -> TEST-*` when adding or changing requirements.
|
|
@@ -1,23 +1,218 @@
|
|
|
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. Supplying `rules` preserves that scoped validation and skips the full-KB advisory scan. Run a full `kb_check` without rule filters before declaring work complete so `qualityDiagnostics[]` includes the full-KB audit-quality review.
|
|
186
|
+
|
|
187
|
+
For meaningful source edits, run impact diagnostics while the edit context is fresh: `kb_check({sourceFiles:["src/changed-file.ts"], includeImpactDiagnostics:true, includeWorkingTreeDiff:true})`. Review `symbol_granularity_violation` as a hard ownership-shape problem and `symbol_semantic_review_needed` as an advisory prompt to inspect whether linked requirements, scenarios, and tests still match the changed behavior or UI copy.
|
|
188
|
+
|
|
189
|
+
## Domain Contradictions and Evolution
|
|
190
|
+
|
|
191
|
+
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.
|
|
192
|
+
|
|
193
|
+
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.
|
|
194
|
+
|
|
195
|
+
## Stale or Dirty KB Handling
|
|
196
|
+
|
|
197
|
+
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.
|
|
198
|
+
|
|
199
|
+
## Anti-Patterns and Remediation
|
|
200
|
+
|
|
201
|
+
| Anti-Pattern | Problem | Remediation |
|
|
202
|
+
|-------------|---------|-------------|
|
|
203
|
+
| Reversed relationship direction | Traceability queries break | Verify direction against the relationship table above |
|
|
204
|
+
| Legacy implements comments | Comments are not durable queryable symbols | Create or update a `symbol` entity and link it to the requirement |
|
|
205
|
+
| Bug-as-flag | `flag` misused for defect tracking | Use `fact` with `fact_kind: observation` or `meta` |
|
|
206
|
+
| Parallel upserts | Lock contention and nondeterminism | Execute `kb_upsert` calls sequentially |
|
|
207
|
+
| Embedded scenarios in reqs | Violates canonical traceability chain | Create separate `req`, `scen`, and `test` entities |
|
|
208
|
+
| Missing `kb_check` | Undetected dangling refs, violations, and full-KB quality diagnostics | Run targeted checks during work, full unfiltered check at completion |
|
|
209
|
+
| Tags as multi-ID lookup | Tags are metadata, not identifiers | Use `kb_query` with explicit `id` values |
|
|
210
|
+
| `relates_to` for strict modeling | Loses contradiction safety | Use `constrains` and `requires_property` instead |
|
|
211
|
+
| `status: implemented` on requirements | Not a valid lifecycle status | Use a valid status such as `closed`, add an `implemented` tag, and link evidence instead |
|
|
212
|
+
|
|
213
|
+
Before/after for reversed direction:
|
|
214
|
+
|
|
215
|
+
- Wrong: `relationships: [{ type: "implements", from: "REQ-001", to: "SYM-001" }]`
|
|
216
|
+
- Right: `relationships: [{ type: "implements", from: "SYM-001", to: "REQ-001" }]`
|
|
217
|
+
|
|
218
|
+
See `resources/workflows.md` for the golden-path discovery to validation sequence.
|
package/package.json
CHANGED
|
@@ -7,6 +7,8 @@ alwaysApply: false
|
|
|
7
7
|
|
|
8
8
|
Before changing production code, discover linked requirements with `kb_search` and `kb_query(sourceFile=...)`.
|
|
9
9
|
|
|
10
|
+
After meaningful source edits, run `kb_check({sourceFiles:[...], includeImpactDiagnostics:true, includeWorkingTreeDiff:true})` while the edit context is fresh. Review symbol granularity and whether linked requirements, scenarios, and tests still cover the changed behavior or UI copy.
|
|
11
|
+
|
|
10
12
|
Preserve the canonical chain `REQ-* -> SCEN-* -> TEST-*` when modeling behavior.
|
|
11
13
|
|
|
12
14
|
Prefer symbol manifest + `executable_for` for test/e2e code. Inline `// implements REQ-xxx` remains acceptable for quick code-only changes.
|
|
@@ -10,12 +10,14 @@ Validate and strengthen traceability before and after code changes.
|
|
|
10
10
|
## MCP workflow
|
|
11
11
|
|
|
12
12
|
- Locate requirements with `kb_search` and inspect exact details with `kb_query`.
|
|
13
|
+
- After meaningful source edits, run `kb_check({sourceFiles:[...], includeImpactDiagnostics:true, includeWorkingTreeDiff:true})` before deciding whether traceability is current.
|
|
13
14
|
- Apply updates with `kb_upsert` for requirements, scenarios, tests, or facts.
|
|
14
15
|
- Validate constraints and consistency with `kb_check`.
|
|
15
16
|
|
|
16
17
|
## Guidance
|
|
17
18
|
|
|
18
19
|
- Prefer source-linked relationships so symbols and files can be traced back cleanly.
|
|
20
|
+
- Treat `symbol_semantic_review_needed` as a prompt to inspect linked requirements/tests; Kibi reports graph links but does not prove prose semantics.
|
|
19
21
|
- Include `kb_query` and `kb_delete` only when explicit cleanups are required.
|
|
20
22
|
- Never directly edit `.kb/**`; all modeling and cleanup goes through MCP tools.
|
|
21
23
|
- Preserve the canonical chain `REQ-* -> SCEN-* -> TEST-*` when adding or changing requirements.
|
|
@@ -1,23 +1,218 @@
|
|
|
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. Supplying `rules` preserves that scoped validation and skips the full-KB advisory scan. Run a full `kb_check` without rule filters before declaring work complete so `qualityDiagnostics[]` includes the full-KB audit-quality review.
|
|
186
|
+
|
|
187
|
+
For meaningful source edits, run impact diagnostics while the edit context is fresh: `kb_check({sourceFiles:["src/changed-file.ts"], includeImpactDiagnostics:true, includeWorkingTreeDiff:true})`. Review `symbol_granularity_violation` as a hard ownership-shape problem and `symbol_semantic_review_needed` as an advisory prompt to inspect whether linked requirements, scenarios, and tests still match the changed behavior or UI copy.
|
|
188
|
+
|
|
189
|
+
## Domain Contradictions and Evolution
|
|
190
|
+
|
|
191
|
+
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.
|
|
192
|
+
|
|
193
|
+
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.
|
|
194
|
+
|
|
195
|
+
## Stale or Dirty KB Handling
|
|
196
|
+
|
|
197
|
+
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.
|
|
198
|
+
|
|
199
|
+
## Anti-Patterns and Remediation
|
|
200
|
+
|
|
201
|
+
| Anti-Pattern | Problem | Remediation |
|
|
202
|
+
|-------------|---------|-------------|
|
|
203
|
+
| Reversed relationship direction | Traceability queries break | Verify direction against the relationship table above |
|
|
204
|
+
| Legacy implements comments | Comments are not durable queryable symbols | Create or update a `symbol` entity and link it to the requirement |
|
|
205
|
+
| Bug-as-flag | `flag` misused for defect tracking | Use `fact` with `fact_kind: observation` or `meta` |
|
|
206
|
+
| Parallel upserts | Lock contention and nondeterminism | Execute `kb_upsert` calls sequentially |
|
|
207
|
+
| Embedded scenarios in reqs | Violates canonical traceability chain | Create separate `req`, `scen`, and `test` entities |
|
|
208
|
+
| Missing `kb_check` | Undetected dangling refs, violations, and full-KB quality diagnostics | Run targeted checks during work, full unfiltered check at completion |
|
|
209
|
+
| Tags as multi-ID lookup | Tags are metadata, not identifiers | Use `kb_query` with explicit `id` values |
|
|
210
|
+
| `relates_to` for strict modeling | Loses contradiction safety | Use `constrains` and `requires_property` instead |
|
|
211
|
+
| `status: implemented` on requirements | Not a valid lifecycle status | Use a valid status such as `closed`, add an `implemented` tag, and link evidence instead |
|
|
212
|
+
|
|
213
|
+
Before/after for reversed direction:
|
|
214
|
+
|
|
215
|
+
- Wrong: `relationships: [{ type: "implements", from: "REQ-001", to: "SYM-001" }]`
|
|
216
|
+
- Right: `relationships: [{ type: "implements", from: "SYM-001", to: "REQ-001" }]`
|
|
217
|
+
|
|
218
|
+
See `resources/workflows.md` for the golden-path discovery to validation sequence.
|