kibi-cursor 0.2.2 → 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 +28 -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 +4 -2
- 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 +4 -2
|
@@ -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,33 @@
|
|
|
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
|
+
|
|
3
31
|
## 0.2.2
|
|
4
32
|
|
|
5
33
|
### 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.
|
|
@@ -182,7 +182,9 @@ Never fire `kb_upsert` calls in parallel. Execute them sequentially to avoid loc
|
|
|
182
182
|
|
|
183
183
|
## Targeted and Final Checks
|
|
184
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.
|
|
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.
|
|
186
188
|
|
|
187
189
|
## Domain Contradictions and Evolution
|
|
188
190
|
|
|
@@ -203,7 +205,7 @@ Call `kb_status` when you suspect the branch KB is stale or when switching conte
|
|
|
203
205
|
| Bug-as-flag | `flag` misused for defect tracking | Use `fact` with `fact_kind: observation` or `meta` |
|
|
204
206
|
| Parallel upserts | Lock contention and nondeterminism | Execute `kb_upsert` calls sequentially |
|
|
205
207
|
| Embedded scenarios in reqs | Violates canonical traceability chain | Create separate `req`, `scen`, and `test` entities |
|
|
206
|
-
| Missing `kb_check` | Undetected dangling refs and
|
|
208
|
+
| Missing `kb_check` | Undetected dangling refs, violations, and full-KB quality diagnostics | Run targeted checks during work, full unfiltered check at completion |
|
|
207
209
|
| Tags as multi-ID lookup | Tags are metadata, not identifiers | Use `kb_query` with explicit `id` values |
|
|
208
210
|
| `relates_to` for strict modeling | Loses contradiction safety | Use `constrains` and `requires_property` instead |
|
|
209
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 |
|
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.
|
|
@@ -182,7 +182,9 @@ Never fire `kb_upsert` calls in parallel. Execute them sequentially to avoid loc
|
|
|
182
182
|
|
|
183
183
|
## Targeted and Final Checks
|
|
184
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.
|
|
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.
|
|
186
188
|
|
|
187
189
|
## Domain Contradictions and Evolution
|
|
188
190
|
|
|
@@ -203,7 +205,7 @@ Call `kb_status` when you suspect the branch KB is stale or when switching conte
|
|
|
203
205
|
| Bug-as-flag | `flag` misused for defect tracking | Use `fact` with `fact_kind: observation` or `meta` |
|
|
204
206
|
| Parallel upserts | Lock contention and nondeterminism | Execute `kb_upsert` calls sequentially |
|
|
205
207
|
| Embedded scenarios in reqs | Violates canonical traceability chain | Create separate `req`, `scen`, and `test` entities |
|
|
206
|
-
| Missing `kb_check` | Undetected dangling refs and
|
|
208
|
+
| Missing `kb_check` | Undetected dangling refs, violations, and full-KB quality diagnostics | Run targeted checks during work, full unfiltered check at completion |
|
|
207
209
|
| Tags as multi-ID lookup | Tags are metadata, not identifiers | Use `kb_query` with explicit `id` values |
|
|
208
210
|
| `relates_to` for strict modeling | Loses contradiction safety | Use `constrains` and `requires_property` instead |
|
|
209
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 |
|