kibi-cursor 2.10.0 → 2.10.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 +16 -0
- package/agent-plugin/plugin.json +1 -1
- package/agent-plugin/skills/kibi-commit-review/SKILL.md +6 -2
- package/agent-plugin/skills/kibi-decisions/SKILL.md +7 -2
- package/agent-plugin/skills/kibi-decisions/resources/signoff-views.md +3 -1
- package/agent-plugin/skills/kibi-usage/SKILL.md +9 -1
- package/dist/.cursor-plugin/plugin.json +1 -1
- package/dist/hook-runner.js +212 -199
- package/dist/skills/.canon-hash.json +4 -4
- package/dist/skills/kibi-commit-review/SKILL.md +6 -2
- package/dist/skills/kibi-decisions/SKILL.md +7 -2
- package/dist/skills/kibi-decisions/resources/signoff-views.md +3 -1
- package/dist/skills/kibi-usage/SKILL.md +9 -1
- package/package.json +2 -2
- package/skills/.canon-hash.json +4 -4
- package/skills/kibi-commit-review/SKILL.md +6 -2
- package/skills/kibi-decisions/SKILL.md +7 -2
- package/skills/kibi-decisions/resources/signoff-views.md +3 -1
- package/skills/kibi-usage/SKILL.md +9 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kibi-cursor",
|
|
3
3
|
"displayName": "Kibi",
|
|
4
|
-
"version": "2.10.
|
|
4
|
+
"version": "2.10.1",
|
|
5
5
|
"description": "Optional Cursor adapter for Kibi. Requires project-local kibi-cli, kibi-mcp, and kibi-core (SWI-Prolog is bundled on Linux and macOS) before the bundled MCP server can start.",
|
|
6
6
|
"license": "AGPL-3.0-or-later",
|
|
7
7
|
"author": {
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# kibi-cursor
|
|
2
2
|
|
|
3
|
+
## 2.10.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- ce41f02: Agents now keep a signoff in the pull request it approves. The guidance used to time the signoff as an end-of-work step and said only that an agent must never set `approved_by` itself, so agents often opened the pull request first and then carried the person's answer in a separate follow-up pull request.
|
|
8
|
+
- kibi-usage 2.37.0, kibi-decisions 1.5.0 and kibi-commit-review 1.4.0 (and the signoff-views resource) say to ask for the signoff before opening or merging the pull request, and to record the person's answer (their name in `approved_by` or a `*_waiver_approved_by` field, their words in `origin.ref` or `approval_ref`) on the same branch and pull request. Writing down an answer the person gave is not self-approval. A pull request that only carries a signoff, firmness or waiver approval is ruled out.
|
|
9
|
+
- The stop-hook signoff reminder (Claude Code, Codex, Cursor, ZCode) adds the same rule. So do the `agent-requirement-unapproved` check action, the `dimension_unrepresented` repair hint and the waiver lines of `kibi proof explain`.
|
|
10
|
+
|
|
11
|
+
- 43d4366: Usage telemetry data is cleaner and more complete. Telemetry is now off when the home directory lies inside the temp directory, as eval, packaging and end-to-end harnesses set it, so each harness run no longer counts as a new install; Kibi's own eval and packed-test sandboxes also set `KIBI_TELEMETRY=0`. Events now name the host agent from `CLAUDECODE`, `CURSOR_AGENT`, `CODEX_SANDBOX`, `GEMINI_CLI`, `OPENCODE`, `AI_AGENT` or the MCP client name, carry a hashed host session id in every host, and say whether they come from a hosted cloud workspace. Failed CLI commands and MCP tool results now carry a fixed error category: the result's error code (for example `upsert_dry_run_invalid`), the failing `kibi doctor` checks, or the `kibi migrate` approval problem. `kibi migrate --apply-safe` now prints the current plan hash when the approved hash is missing or out of date.
|
|
12
|
+
|
|
13
|
+
Hooks in Claude Code, Codex, Cursor, ZCode and OpenCode now all send the anonymous `kibi_hook` event (before, only Claude Code did, and only in diagnostic mode for the others), and each hook remembers, as hashes in `telemetry-sessions.json`, which host session last ran in the workspace. CLI and MCP events take the session id from `KIBI_SESSION_ID`, `CLAUDE_CODE_SESSION_ID` or `CODEX_THREAD_ID` when the host exposes one, and otherwise from that workspace marker (at most 30 minutes old), so events from Cursor and OpenCode sessions, which expose no session variable, can be grouped too. Every host's hook also sends the queue when it is due, and right away at the end of a turn.
|
|
14
|
+
|
|
15
|
+
- Updated dependencies [ce41f02]
|
|
16
|
+
- Updated dependencies [43d4366]
|
|
17
|
+
- kibi-agent-core@0.11.0
|
|
18
|
+
|
|
3
19
|
## 2.10.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
package/agent-plugin/plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
|
|
3
3
|
"name": "kibi",
|
|
4
|
-
"version": "2.10.
|
|
4
|
+
"version": "2.10.1",
|
|
5
5
|
"description": "Repo-local, per-branch, queryable knowledge base. Portable Agent Plugin packaging Kibi's Agent Skills and MCP server.",
|
|
6
6
|
"author": { "name": "Kibi" },
|
|
7
7
|
"homepage": "https://looted.github.io/kibi/",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: kibi-commit-review
|
|
3
3
|
name: kibi-commit-review
|
|
4
4
|
description: "Use when kibi check --staged or the Kibi pre-commit hook blocks a commit (kibi_impact_evidence_missing, symbols_manifest_stale, symbol_granularity_violation, symbol-coverage, kibi check-generated drift, Staged impact review failed), or when preparing a commit or pull-request impact review. Covers reading the per-file Detail lines, authoring .kb/symbols.yaml symbol entries through kb_upsert, staging the tracked Kibi evidence with git add (symbol coordinates are derived and never staged), kb_prepare_impact_review for a staged or diff scope, the kibi signoff requirements summary to show before a commit, and how merge commits and migration renames are judged."
|
|
5
|
-
version: 1.
|
|
5
|
+
version: 1.4.0
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -91,7 +91,11 @@ apps); never attach the `.html` as a file, which chat apps show as raw source;
|
|
|
91
91
|
past 15 requirements the Markdown stops and only the page lists them all.
|
|
92
92
|
Host details: `kibi-decisions`, `resources/signoff-views.md`. `--no-proof` skips the proof lookup, which reads coverage and is slow
|
|
93
93
|
on a large knowledge base. The summary is not an approval: never set
|
|
94
|
-
`approved_by` or `origin.ref` from it.
|
|
94
|
+
`approved_by` or `origin.ref` from it. Show it before you open or merge the
|
|
95
|
+
pull request. When the person answers, record their answer in the same
|
|
96
|
+
change (their name in `approved_by`, their words in `origin.ref` or
|
|
97
|
+
`approval_ref`) and push it to the same pull request; never move a signoff,
|
|
98
|
+
firmness or waiver approval into a separate pull request.
|
|
95
99
|
|
|
96
100
|
## Impact reviews
|
|
97
101
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: kibi-decisions
|
|
3
3
|
name: kibi-decisions
|
|
4
4
|
description: "Use when the person states a rule or decision (must, never, always, from now on, we decided), when a Kibi hook asks to confirm or warns about an edit to code that implements a firm requirement, when the Stop hook says source files changed but nothing was recorded, when kb_check quotes requirement_statement_unverified, or when a request conflicts with a recorded requirement or ADR. Covers reading firmness and origin, recording a person's rule as firm with origin.ref, superseding with a Why this changed section, the kb_compile_intent unresolved/reviewCandidates/conflictReviews loop, asking before overriding a firm rule, and putting decisions to the person as one numbered kibi signoff --questions view."
|
|
5
|
-
version: 1.
|
|
5
|
+
version: 1.5.0
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -115,7 +115,12 @@ again until none is open, then record each rule with their words in
|
|
|
115
115
|
`origin.ref`. Fields and outputs: `resources/signoff-views.md`.
|
|
116
116
|
|
|
117
117
|
Never invent words for `origin.ref`, never set `approved_by` yourself, and
|
|
118
|
-
mark your own picks `default` and guesses `exploratory`.
|
|
118
|
+
mark your own picks `default` and guesses `exploratory`. Once the person has
|
|
119
|
+
answered, recording their answer (their name in `approved_by` or a
|
|
120
|
+
`*_waiver_approved_by` field, their words in `origin.ref` or `approval_ref`)
|
|
121
|
+
is yours to do: put it on the branch of the change it approves and push it to
|
|
122
|
+
that pull request, never to a separate one. Ask before you open or merge the
|
|
123
|
+
pull request, so the answer lands in it. Payload shapes,
|
|
119
124
|
refusal messages and the `kb_compile_intent` review loop are in
|
|
120
125
|
`resources/decision-records.md`.
|
|
121
126
|
|
|
@@ -51,7 +51,9 @@ writes and opens the page; `--format json` prints the view.
|
|
|
51
51
|
The person answers by number ("1 yes, 2 exploratory, 3 reword: ..."). Copy
|
|
52
52
|
each answer into `answer`, render again, and record the rules only once every
|
|
53
53
|
question is answered. An answer is the person's words: quote it in
|
|
54
|
-
`origin.ref`; a view itself is never an approval.
|
|
54
|
+
`origin.ref`; a view itself is never an approval. Record the answers on the
|
|
55
|
+
branch of the change they approve and push them to its pull request, never to
|
|
56
|
+
a separate one.
|
|
55
57
|
|
|
56
58
|
## Summary contents
|
|
57
59
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: kibi-usage
|
|
3
3
|
name: Kibi Usage
|
|
4
4
|
description: Use Kibi's source-first, exact-Git, migration-aware, proof-aware operations safely across MCP or the trusted local CLI, including partial completion repair.
|
|
5
|
-
version: 2.
|
|
5
|
+
version: 2.37.0
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -372,6 +372,14 @@ human sets `approved_by`; `kb_check` flags approvals an agent recorded without
|
|
|
372
372
|
corroboration. Never fill in an approval yourself. Record why a requirement
|
|
373
373
|
exists in `rationale`, or link the ADR that explains it.
|
|
374
374
|
|
|
375
|
+
A signoff belongs to the change it approves. Ask for it before you open or
|
|
376
|
+
merge the pull request, and when the person answers, record their answer
|
|
377
|
+
(`approved_by` or a `*_waiver_approved_by` field set to them, their words in
|
|
378
|
+
`origin.ref` or `approval_ref`) on the same branch and push it to the same pull
|
|
379
|
+
request. Writing down an answer the person gave is not approving it yourself.
|
|
380
|
+
Never open a separate pull request only to carry a signoff, firmness or waiver
|
|
381
|
+
approval.
|
|
382
|
+
|
|
375
383
|
## Decision firmness
|
|
376
384
|
|
|
377
385
|
Requirements and ADRs carry `firmness`, which says what you may do with them.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kibi-cursor",
|
|
3
3
|
"displayName": "Kibi",
|
|
4
|
-
"version": "2.10.
|
|
4
|
+
"version": "2.10.1",
|
|
5
5
|
"description": "Optional Cursor adapter for Kibi. Requires project-local kibi-cli, kibi-mcp, and kibi-core (SWI-Prolog is bundled on Linux and macOS) before the bundled MCP server can start.",
|
|
6
6
|
"license": "AGPL-3.0-or-later",
|
|
7
7
|
"author": {
|
package/dist/hook-runner.js
CHANGED
|
@@ -4,7 +4,7 @@ import fs from "node:fs";
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
6
6
|
import { captureReminder, claimCaptureReminder, claimSignoffReminder, confirmFirmEdits, firmEditNotice, firmRequirementsTouched, hasDecisionFlag, holdRuleNote, isRequirementUpsert, markDecisionFlag, recordRequest, settleFirmRequirements, settledFirmRequirements, signoffReminder, takeRuleNote, } from "kibi-agent-core/decision-guard";
|
|
7
|
-
import { appendHookUsageRows, editTraces,
|
|
7
|
+
import { appendHookUsageRows, editTraces, finishHookTelemetry, hookTracesWanted, kbUsageTrace, readPackageVersion, } from "kibi-agent-core/hook-usage-log";
|
|
8
8
|
import { stampKibiWorkspace } from "kibi-agent-core/kb-mcp-tools";
|
|
9
9
|
import { createEntitySummarizer, editFocus, fileKnowledgeSnippet, implementedRequirementIds, } from "kibi-agent-core/snippets";
|
|
10
10
|
import { preEditGuidance, readGuidance, writeGuidance } from "./guidance.js";
|
|
@@ -68,7 +68,7 @@ function recordToolTelemetry(input, workspaceRoot, stateDir, startedAt, env) {
|
|
|
68
68
|
// rationale: appendHookUsageRows applies the same opt-in; this guard only
|
|
69
69
|
// skips reading the index when telemetry is off.
|
|
70
70
|
// Stryker disable next-line ConditionalExpression
|
|
71
|
-
if (!
|
|
71
|
+
if (!hookTracesWanted(env))
|
|
72
72
|
return;
|
|
73
73
|
const kbUsage = kbUsageTrace(input.toolName, input.toolInput);
|
|
74
74
|
if (!kbUsage && !isKnownEditableTool(input.toolName))
|
|
@@ -166,157 +166,89 @@ export async function runHook(rawInput, environment = {}) {
|
|
|
166
166
|
stateDir,
|
|
167
167
|
sessionId: input.conversationId,
|
|
168
168
|
};
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
{
|
|
180
|
-
const advisory = interfaceAdvisory(initialState.mcpState, workspaceTrusted);
|
|
181
|
-
return advisory ? { additional_context: advisory } : emptyResult();
|
|
182
|
-
}
|
|
183
|
-
case "preToolUse": {
|
|
184
|
-
// Name the agent's workspace on every Kibi MCP call so the launcher
|
|
185
|
-
// answers from it, also for agents working in a git worktree. The
|
|
186
|
-
// per-call cwd wins over workspace_roots, which can be the window's
|
|
187
|
-
// folders rather than the agent's checkout.
|
|
188
|
-
const stamped = stampKibiWorkspace(input.toolName, input.toolInput, kibiWorkspaceFor(input.cwd ?? input.workspaceRoots?.[0]));
|
|
189
|
-
if (stamped) {
|
|
190
|
-
return { updated_input: stamped };
|
|
191
|
-
}
|
|
192
|
-
const explicitPaths = extractExplicitPathFields(input.toolInput);
|
|
193
|
-
const hasDirectKbEdit = isEditLikeTool(input.toolName) && explicitPaths.some(isDirectKbPath);
|
|
194
|
-
if (hasDirectKbEdit) {
|
|
195
|
-
return {
|
|
196
|
-
permission: "allow",
|
|
197
|
-
agent_message: DIRECT_KB_EDIT_WARNING,
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
const primaryPath = resolvePrimaryPath(input);
|
|
201
|
-
if (!primaryPath || !kibiReady || !isKnownEditableTool(input.toolName)) {
|
|
202
|
-
return emptyResult();
|
|
203
|
-
}
|
|
204
|
-
const relativePath = toRepoRelativePath(primaryPath, cwd);
|
|
205
|
-
const state = loadHookState(stateDir);
|
|
206
|
-
const linked = getSourceLinkedSymbols(cwd, primaryPath, stateDir);
|
|
207
|
-
const focus = editFocus(path.resolve(cwd, primaryPath), input.toolInput);
|
|
208
|
-
const ruleNote = takeRuleNote(session);
|
|
209
|
-
const notice = firmNotice(cwd, linked, focus, session, environment.env ?? process.env);
|
|
210
|
-
const guidance = hasGuidedPath(state, "pre-edit", relativePath)
|
|
211
|
-
? undefined
|
|
212
|
-
: preEditGuidance(primaryPath, {
|
|
213
|
-
cwd,
|
|
214
|
-
hasKibi: kibiReady,
|
|
215
|
-
mcpState: state.mcpState,
|
|
216
|
-
workspaceTrusted,
|
|
217
|
-
// A file that implements requirements always gets the shared
|
|
218
|
-
// snippet, so the bare linked-requirement wording is never needed.
|
|
219
|
-
knowledge: knowledgeFor(cwd, linked, "edit", focus),
|
|
220
|
-
});
|
|
221
|
-
if (guidance) {
|
|
222
|
-
rememberGuidedPath(stateDir, "pre-edit", relativePath);
|
|
223
|
-
}
|
|
224
|
-
const parts = [ruleNote, notice, guidance].filter((part) => part !== undefined);
|
|
225
|
-
return parts.length > 0
|
|
226
|
-
? { permission: "allow", agent_message: parts.join("\n\n") }
|
|
227
|
-
: emptyResult();
|
|
228
|
-
}
|
|
229
|
-
// implements REQ-agent-hosts-decision-guard
|
|
230
|
-
case "beforeSubmitPrompt": {
|
|
231
|
-
// Cursor's prompt hook cannot add context: the request's rule note
|
|
232
|
-
// waits for the next pre-edit message.
|
|
233
|
-
if (kibiReady && input.prompt) {
|
|
234
|
-
const rule = recordRequest(session, input.prompt);
|
|
235
|
-
if (rule !== undefined)
|
|
236
|
-
holdRuleNote(session, rule);
|
|
237
|
-
}
|
|
238
|
-
return { continue: true };
|
|
239
|
-
}
|
|
240
|
-
case "beforeReadFile": {
|
|
241
|
-
const primaryPath = resolvePrimaryPath(input);
|
|
242
|
-
if (!primaryPath || !kibiReady) {
|
|
243
|
-
return { permission: "allow" };
|
|
244
|
-
}
|
|
245
|
-
const relativePath = toRepoRelativePath(primaryPath, cwd);
|
|
246
|
-
const state = loadHookState(stateDir);
|
|
247
|
-
if (hasGuidedPath(state, "read", relativePath)) {
|
|
248
|
-
return { permission: "allow" };
|
|
249
|
-
}
|
|
250
|
-
const guidance = readGuidance(primaryPath, {
|
|
251
|
-
cwd,
|
|
252
|
-
hasKibi: kibiReady,
|
|
253
|
-
mcpState: state.mcpState,
|
|
254
|
-
workspaceTrusted,
|
|
255
|
-
knowledge: knowledgeFor(cwd, getSourceLinkedSymbols(cwd, primaryPath, stateDir),
|
|
256
|
-
// rationale: the snippet only special-cases "edit", so any other
|
|
257
|
-
// surface literal renders the same read snippet.
|
|
258
|
-
// Stryker disable next-line StringLiteral
|
|
259
|
-
"read"),
|
|
260
|
-
});
|
|
261
|
-
if (!guidance) {
|
|
262
|
-
return { permission: "allow" };
|
|
263
|
-
}
|
|
264
|
-
rememberGuidedPath(stateDir, "read", relativePath);
|
|
265
|
-
return {
|
|
266
|
-
permission: "allow",
|
|
267
|
-
agent_message: guidance,
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
case "postToolUse": {
|
|
271
|
-
if (kibiReady) {
|
|
272
|
-
try {
|
|
273
|
-
recordToolTelemetry(input, cwd, stateDir, startedAt, environment.env);
|
|
169
|
+
try {
|
|
170
|
+
switch (input.event) {
|
|
171
|
+
case "sessionStart":
|
|
172
|
+
if (!kibiReady) {
|
|
173
|
+
const advisory = interfaceAdvisory(initialState.mcpState, workspaceTrusted);
|
|
174
|
+
return {
|
|
175
|
+
additional_context: advisory
|
|
176
|
+
? `${BOOTSTRAP_REMINDER}\n${advisory}`
|
|
177
|
+
: BOOTSTRAP_REMINDER,
|
|
178
|
+
};
|
|
274
179
|
}
|
|
275
|
-
|
|
276
|
-
|
|
180
|
+
{
|
|
181
|
+
const advisory = interfaceAdvisory(initialState.mcpState, workspaceTrusted);
|
|
182
|
+
return advisory ? { additional_context: advisory } : emptyResult();
|
|
277
183
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
if (isPlanDeliveryTool(input.toolName)) {
|
|
287
|
-
recordPlanDelivered(stateDir);
|
|
288
|
-
}
|
|
289
|
-
const explicitPaths = extractExplicitPathFields(input.toolInput);
|
|
290
|
-
if (isKnownEditableTool(input.toolName)) {
|
|
291
|
-
const dirtyPaths = explicitPaths
|
|
292
|
-
.map((candidate) => toRepoRelativePath(candidate, cwd))
|
|
293
|
-
.filter((candidate) => isMeaningfulTrackedPath(candidate) ||
|
|
294
|
-
isKbFreshnessRelevantPath(candidate));
|
|
295
|
-
if (dirtyPaths.length > 0) {
|
|
296
|
-
addDirtyPaths(stateDir, dirtyPaths);
|
|
184
|
+
case "preToolUse": {
|
|
185
|
+
// Name the agent's workspace on every Kibi MCP call so the launcher
|
|
186
|
+
// answers from it, also for agents working in a git worktree. The
|
|
187
|
+
// per-call cwd wins over workspace_roots, which can be the window's
|
|
188
|
+
// folders rather than the agent's checkout.
|
|
189
|
+
const stamped = stampKibiWorkspace(input.toolName, input.toolInput, kibiWorkspaceFor(input.cwd ?? input.workspaceRoots?.[0]));
|
|
190
|
+
if (stamped) {
|
|
191
|
+
return { updated_input: stamped };
|
|
297
192
|
}
|
|
298
|
-
|
|
299
|
-
|
|
193
|
+
const explicitPaths = extractExplicitPathFields(input.toolInput);
|
|
194
|
+
const hasDirectKbEdit = isEditLikeTool(input.toolName) && explicitPaths.some(isDirectKbPath);
|
|
195
|
+
if (hasDirectKbEdit) {
|
|
196
|
+
return {
|
|
197
|
+
permission: "allow",
|
|
198
|
+
agent_message: DIRECT_KB_EDIT_WARNING,
|
|
199
|
+
};
|
|
300
200
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
// implements REQ-kibi-signoff-views
|
|
307
|
-
if (isRequirementUpsert(input.toolInput)) {
|
|
308
|
-
markDecisionFlag(session, "requirement-recorded");
|
|
201
|
+
const primaryPath = resolvePrimaryPath(input);
|
|
202
|
+
if (!primaryPath ||
|
|
203
|
+
!kibiReady ||
|
|
204
|
+
!isKnownEditableTool(input.toolName)) {
|
|
205
|
+
return emptyResult();
|
|
309
206
|
}
|
|
207
|
+
const relativePath = toRepoRelativePath(primaryPath, cwd);
|
|
208
|
+
const state = loadHookState(stateDir);
|
|
209
|
+
const linked = getSourceLinkedSymbols(cwd, primaryPath, stateDir);
|
|
210
|
+
const focus = editFocus(path.resolve(cwd, primaryPath), input.toolInput);
|
|
211
|
+
const ruleNote = takeRuleNote(session);
|
|
212
|
+
const notice = firmNotice(cwd, linked, focus, session, environment.env ?? process.env);
|
|
213
|
+
const guidance = hasGuidedPath(state, "pre-edit", relativePath)
|
|
214
|
+
? undefined
|
|
215
|
+
: preEditGuidance(primaryPath, {
|
|
216
|
+
cwd,
|
|
217
|
+
hasKibi: kibiReady,
|
|
218
|
+
mcpState: state.mcpState,
|
|
219
|
+
workspaceTrusted,
|
|
220
|
+
// A file that implements requirements always gets the shared
|
|
221
|
+
// snippet, so the bare linked-requirement wording is never needed.
|
|
222
|
+
knowledge: knowledgeFor(cwd, linked, "edit", focus),
|
|
223
|
+
});
|
|
224
|
+
if (guidance) {
|
|
225
|
+
rememberGuidedPath(stateDir, "pre-edit", relativePath);
|
|
226
|
+
}
|
|
227
|
+
const parts = [ruleNote, notice, guidance].filter((part) => part !== undefined);
|
|
228
|
+
return parts.length > 0
|
|
229
|
+
? { permission: "allow", agent_message: parts.join("\n\n") }
|
|
230
|
+
: emptyResult();
|
|
310
231
|
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
232
|
+
// implements REQ-agent-hosts-decision-guard
|
|
233
|
+
case "beforeSubmitPrompt": {
|
|
234
|
+
// Cursor's prompt hook cannot add context: the request's rule note
|
|
235
|
+
// waits for the next pre-edit message.
|
|
236
|
+
if (kibiReady && input.prompt) {
|
|
237
|
+
const rule = recordRequest(session, input.prompt);
|
|
238
|
+
if (rule !== undefined)
|
|
239
|
+
holdRuleNote(session, rule);
|
|
240
|
+
}
|
|
241
|
+
return { continue: true };
|
|
314
242
|
}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
243
|
+
case "beforeReadFile": {
|
|
244
|
+
const primaryPath = resolvePrimaryPath(input);
|
|
245
|
+
if (!primaryPath || !kibiReady) {
|
|
246
|
+
return { permission: "allow" };
|
|
247
|
+
}
|
|
248
|
+
const relativePath = toRepoRelativePath(primaryPath, cwd);
|
|
249
|
+
const state = loadHookState(stateDir);
|
|
318
250
|
if (hasGuidedPath(state, "read", relativePath)) {
|
|
319
|
-
return
|
|
251
|
+
return { permission: "allow" };
|
|
320
252
|
}
|
|
321
253
|
const guidance = readGuidance(primaryPath, {
|
|
322
254
|
cwd,
|
|
@@ -324,77 +256,158 @@ export async function runHook(rawInput, environment = {}) {
|
|
|
324
256
|
mcpState: state.mcpState,
|
|
325
257
|
workspaceTrusted,
|
|
326
258
|
knowledge: knowledgeFor(cwd, getSourceLinkedSymbols(cwd, primaryPath, stateDir),
|
|
327
|
-
// rationale:
|
|
259
|
+
// rationale: the snippet only special-cases "edit", so any other
|
|
260
|
+
// surface literal renders the same read snippet.
|
|
328
261
|
// Stryker disable next-line StringLiteral
|
|
329
262
|
"read"),
|
|
330
263
|
});
|
|
331
264
|
if (!guidance) {
|
|
332
|
-
return
|
|
265
|
+
return { permission: "allow" };
|
|
333
266
|
}
|
|
334
267
|
rememberGuidedPath(stateDir, "read", relativePath);
|
|
335
|
-
return {
|
|
268
|
+
return {
|
|
269
|
+
permission: "allow",
|
|
270
|
+
agent_message: guidance,
|
|
271
|
+
};
|
|
336
272
|
}
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
273
|
+
case "postToolUse": {
|
|
274
|
+
if (kibiReady) {
|
|
275
|
+
try {
|
|
276
|
+
recordToolTelemetry(input, cwd, stateDir, startedAt, environment.env);
|
|
277
|
+
}
|
|
278
|
+
catch {
|
|
279
|
+
// Telemetry is best effort and must never change the hook's output.
|
|
280
|
+
}
|
|
343
281
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
}
|
|
351
|
-
if (
|
|
282
|
+
const kbToolCall = extractKbMcpToolCall(input.toolName, input.toolInput);
|
|
283
|
+
if (kbToolCall) {
|
|
284
|
+
recordKbMcpTool(stateDir, kbToolCall.toolName, {
|
|
285
|
+
impactCheckRun: kbToolCall.impactCheckRun,
|
|
286
|
+
sourceFiles: kbToolCall.sourceFiles,
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
if (isPlanDeliveryTool(input.toolName)) {
|
|
290
|
+
recordPlanDelivered(stateDir);
|
|
291
|
+
}
|
|
292
|
+
const explicitPaths = extractExplicitPathFields(input.toolInput);
|
|
293
|
+
if (isKnownEditableTool(input.toolName)) {
|
|
294
|
+
const dirtyPaths = explicitPaths
|
|
295
|
+
.map((candidate) => toRepoRelativePath(candidate, cwd))
|
|
296
|
+
.filter((candidate) => isMeaningfulTrackedPath(candidate) ||
|
|
297
|
+
isKbFreshnessRelevantPath(candidate));
|
|
298
|
+
if (dirtyPaths.length > 0) {
|
|
299
|
+
addDirtyPaths(stateDir, dirtyPaths);
|
|
300
|
+
}
|
|
301
|
+
if (dirtyPaths.some(isSourceImpactRelevantPath)) {
|
|
302
|
+
markDecisionFlag(session, "source-edited");
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if (kbToolCall?.toolName === "kb_upsert" ||
|
|
306
|
+
kbUsageTrace(input.toolName, input.toolInput)?.kbOperation ===
|
|
307
|
+
"kb_upsert") {
|
|
308
|
+
markDecisionFlag(session, "kb-recorded");
|
|
309
|
+
// implements REQ-kibi-signoff-views
|
|
310
|
+
if (isRequirementUpsert(input.toolInput)) {
|
|
311
|
+
markDecisionFlag(session, "requirement-recorded");
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
const primaryPath = resolvePrimaryPath(input);
|
|
315
|
+
if (!primaryPath || !kibiReady) {
|
|
352
316
|
return emptyResult();
|
|
353
317
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
318
|
+
const relativePath = toRepoRelativePath(primaryPath, cwd);
|
|
319
|
+
const state = loadHookState(stateDir);
|
|
320
|
+
if (isReadLikeTool(input.toolName)) {
|
|
321
|
+
if (hasGuidedPath(state, "read", relativePath)) {
|
|
322
|
+
return emptyResult();
|
|
323
|
+
}
|
|
324
|
+
const guidance = readGuidance(primaryPath, {
|
|
325
|
+
cwd,
|
|
326
|
+
hasKibi: kibiReady,
|
|
327
|
+
mcpState: state.mcpState,
|
|
328
|
+
workspaceTrusted,
|
|
329
|
+
knowledge: knowledgeFor(cwd, getSourceLinkedSymbols(cwd, primaryPath, stateDir),
|
|
330
|
+
// rationale: as above, only "edit" changes the snippet.
|
|
331
|
+
// Stryker disable next-line StringLiteral
|
|
332
|
+
"read"),
|
|
333
|
+
});
|
|
334
|
+
if (!guidance) {
|
|
335
|
+
return emptyResult();
|
|
336
|
+
}
|
|
337
|
+
rememberGuidedPath(stateDir, "read", relativePath);
|
|
338
|
+
return { additional_context: guidance };
|
|
339
|
+
}
|
|
340
|
+
if (isEditLikeTool(input.toolName)) {
|
|
341
|
+
// rationale: the runner only ever passes "read" or "write"; an empty
|
|
342
|
+
// kind selects the same write bucket.
|
|
343
|
+
// Stryker disable StringLiteral
|
|
344
|
+
if (hasGuidedPath(state, "write", relativePath)) {
|
|
345
|
+
return emptyResult();
|
|
346
|
+
}
|
|
347
|
+
// Stryker restore
|
|
348
|
+
const guidance = writeGuidance(primaryPath, {
|
|
349
|
+
cwd,
|
|
350
|
+
hasKibi: kibiReady,
|
|
351
|
+
mcpState: state.mcpState,
|
|
352
|
+
workspaceTrusted,
|
|
353
|
+
});
|
|
354
|
+
if (!guidance) {
|
|
355
|
+
return emptyResult();
|
|
356
|
+
}
|
|
357
|
+
// rationale: same bucket equivalence as the lookup above.
|
|
358
|
+
// Stryker disable StringLiteral
|
|
359
|
+
rememberGuidedPath(stateDir, "write", relativePath);
|
|
360
|
+
// Stryker restore
|
|
361
|
+
return { additional_context: guidance };
|
|
362
|
+
}
|
|
363
|
+
return emptyResult();
|
|
359
364
|
}
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
365
|
+
case "stop": {
|
|
366
|
+
const state = loadHookState(stateDir);
|
|
367
|
+
const shouldClearSession = state.dirtyPaths.length > 0 ||
|
|
368
|
+
state.kbCheckRun ||
|
|
369
|
+
state.planDelivered;
|
|
370
|
+
if (input.status === "aborted" || input.status === "error") {
|
|
371
|
+
if (shouldClearSession) {
|
|
372
|
+
clearSessionHookState(stateDir);
|
|
373
|
+
}
|
|
374
|
+
return emptyResult();
|
|
375
|
+
}
|
|
376
|
+
// implements REQ-agent-hosts-decision-guard
|
|
377
|
+
// Source changed and nothing was recorded: the follow-up asks for the
|
|
378
|
+
// decision to be recorded, once per conversation.
|
|
379
|
+
const capture = claimCaptureReminder(session)
|
|
380
|
+
? captureReminder(hasDecisionFlag(session, "rule-prompt"))
|
|
381
|
+
: undefined;
|
|
382
|
+
// implements REQ-kibi-signoff-views
|
|
383
|
+
// Requirements were written without a signoff view since: ask once.
|
|
384
|
+
// A recorded requirement also counts as recorded knowledge, so this
|
|
385
|
+
// never coincides with the capture request above.
|
|
386
|
+
const signoff = claimSignoffReminder(session, cwd)
|
|
387
|
+
? signoffReminder()
|
|
388
|
+
: undefined;
|
|
389
|
+
const followupMessage = [capture, signoff, stopFollowupMessage(state)]
|
|
390
|
+
.filter((part) => part !== undefined)
|
|
391
|
+
.join("\n");
|
|
392
|
+
if (followupMessage) {
|
|
393
|
+
clearSessionHookState(stateDir);
|
|
394
|
+
return { followup_message: followupMessage };
|
|
395
|
+
}
|
|
366
396
|
if (shouldClearSession) {
|
|
367
397
|
clearSessionHookState(stateDir);
|
|
368
398
|
}
|
|
369
399
|
return emptyResult();
|
|
370
400
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
// decision to be recorded, once per conversation.
|
|
374
|
-
const capture = claimCaptureReminder(session)
|
|
375
|
-
? captureReminder(hasDecisionFlag(session, "rule-prompt"))
|
|
376
|
-
: undefined;
|
|
377
|
-
// implements REQ-kibi-signoff-views
|
|
378
|
-
// Requirements were written without a signoff view since: ask once.
|
|
379
|
-
// A recorded requirement also counts as recorded knowledge, so this
|
|
380
|
-
// never coincides with the capture request above.
|
|
381
|
-
const signoff = claimSignoffReminder(session, cwd)
|
|
382
|
-
? signoffReminder()
|
|
383
|
-
: undefined;
|
|
384
|
-
const followupMessage = [capture, signoff, stopFollowupMessage(state)]
|
|
385
|
-
.filter((part) => part !== undefined)
|
|
386
|
-
.join("\n");
|
|
387
|
-
if (followupMessage) {
|
|
388
|
-
clearSessionHookState(stateDir);
|
|
389
|
-
return { followup_message: followupMessage };
|
|
390
|
-
}
|
|
391
|
-
if (shouldClearSession) {
|
|
392
|
-
clearSessionHookState(stateDir);
|
|
393
|
-
}
|
|
394
|
-
return emptyResult();
|
|
401
|
+
default:
|
|
402
|
+
return emptyResult();
|
|
395
403
|
}
|
|
396
|
-
|
|
397
|
-
|
|
404
|
+
}
|
|
405
|
+
finally {
|
|
406
|
+
await finishHookTelemetry({
|
|
407
|
+
event: input.event,
|
|
408
|
+
workspaceRoot: kibiReady ? cwd : undefined,
|
|
409
|
+
sessionId: input.conversationId,
|
|
410
|
+
}, environment.env ?? process.env);
|
|
398
411
|
}
|
|
399
412
|
}
|
|
400
413
|
export async function main() {
|
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
"kibi-bootstrap/resources/branch-lifecycle.md": "c854264ce888439140883a3fc636db5e522f020dd27b30a5c1ecc4105b64ed13",
|
|
5
5
|
"kibi-bootstrap/resources/operation-access.md": "b5a6a59e72d800c376e7fad79132897623c32a0ce152a1e8d73f9628b444db51",
|
|
6
6
|
"kibi-bootstrap/resources/source-authoring.md": "bf296e62f69474e01797d6cb9469bf624551dca834dd188abb6e705bd96fa586",
|
|
7
|
-
"kibi-commit-review/SKILL.md": "
|
|
7
|
+
"kibi-commit-review/SKILL.md": "bec768ad3e4cd4e782e9e13360b69bcd40a0964b305909818115d7f9e8d282d9",
|
|
8
8
|
"kibi-commit-review/resources/staged-gate.md": "37f750f327bb9202c1f30989763f4f1205b906cf672318ca50887d7984bc3e08",
|
|
9
|
-
"kibi-decisions/SKILL.md": "
|
|
9
|
+
"kibi-decisions/SKILL.md": "d91f784410251095e9d881bce751728cc4596858a518fb24f5e5d38c940bab50",
|
|
10
10
|
"kibi-decisions/resources/decision-records.md": "b201e619c48daf6ebe5989991a96f6c0573adb6c37abf814b9d34b7a1cd423c6",
|
|
11
|
-
"kibi-decisions/resources/signoff-views.md": "
|
|
11
|
+
"kibi-decisions/resources/signoff-views.md": "84eb2b7123e54047205b84af6fbf60c910ebcaaf98023e5812f3de9b65a4871c",
|
|
12
12
|
"kibi-freshness/SKILL.md": "b5c4f24bebdb5b4e0d04c2fa1176fc33ace35334b0c0b6ca943d6f445dc9b69e",
|
|
13
13
|
"kibi-freshness/resources/branch-lifecycle.md": "ebc01b19fe3dca8df5fc0175978963f6f1204f71f7c805cb2a5fb1b277ac78e4",
|
|
14
14
|
"kibi-freshness/resources/operation-access.md": "4e1db9294ee540cd29b8b3a2532a81e7894d5b4228b39e99ba48b37212f489f3",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"kibi-traceability/resources/operation-access.md": "39f7972ab7f4ae7479e78f7072bb50e8e6c4cdf4f857425f69d2522d37db437c",
|
|
19
19
|
"kibi-traceability/resources/source-authoring.md": "408c6ee2bef1b84e0194c0538ef929c26a0a617e631b2234247388140dbbdd08",
|
|
20
20
|
"kibi-traceability/resources/traceability.md": "38c290a0bc71bd1692e115f22694743946e2f69630e134acfd43cee5f613fb88",
|
|
21
|
-
"kibi-usage/SKILL.md": "
|
|
21
|
+
"kibi-usage/SKILL.md": "24c7148c78501a1fa8d9374e96c9a2c5503d04347c186c958cbd768cd67abd88",
|
|
22
22
|
"kibi-usage/resources/branch-lifecycle.md": "f1bf359e9826e83c548f3cd0287f8175a62456527b0132b06b3f9f74aa59b7d6",
|
|
23
23
|
"kibi-usage/resources/fact-lanes.md": "7d487ffb794f6a7c32afabc7756a265a258b072ca83510ddb40d275863d44648",
|
|
24
24
|
"kibi-usage/resources/kb-improvement.md": "a8408fce27342bdce6415a6718599e53fe00bb33aa1fd3dc42353ec6f61adcd7",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: kibi-commit-review
|
|
3
3
|
name: kibi-commit-review
|
|
4
4
|
description: "Use when kibi check --staged or the Kibi pre-commit hook blocks a commit (kibi_impact_evidence_missing, symbols_manifest_stale, symbol_granularity_violation, symbol-coverage, kibi check-generated drift, Staged impact review failed), or when preparing a commit or pull-request impact review. Covers reading the per-file Detail lines, authoring .kb/symbols.yaml symbol entries through kb_upsert, staging the tracked Kibi evidence with git add (symbol coordinates are derived and never staged), kb_prepare_impact_review for a staged or diff scope, the kibi signoff requirements summary to show before a commit, and how merge commits and migration renames are judged."
|
|
5
|
-
version: 1.
|
|
5
|
+
version: 1.4.0
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -91,7 +91,11 @@ apps); never attach the `.html` as a file, which chat apps show as raw source;
|
|
|
91
91
|
past 15 requirements the Markdown stops and only the page lists them all.
|
|
92
92
|
Host details: `kibi-decisions`, `resources/signoff-views.md`. `--no-proof` skips the proof lookup, which reads coverage and is slow
|
|
93
93
|
on a large knowledge base. The summary is not an approval: never set
|
|
94
|
-
`approved_by` or `origin.ref` from it.
|
|
94
|
+
`approved_by` or `origin.ref` from it. Show it before you open or merge the
|
|
95
|
+
pull request. When the person answers, record their answer in the same
|
|
96
|
+
change (their name in `approved_by`, their words in `origin.ref` or
|
|
97
|
+
`approval_ref`) and push it to the same pull request; never move a signoff,
|
|
98
|
+
firmness or waiver approval into a separate pull request.
|
|
95
99
|
|
|
96
100
|
## Impact reviews
|
|
97
101
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: kibi-decisions
|
|
3
3
|
name: kibi-decisions
|
|
4
4
|
description: "Use when the person states a rule or decision (must, never, always, from now on, we decided), when a Kibi hook asks to confirm or warns about an edit to code that implements a firm requirement, when the Stop hook says source files changed but nothing was recorded, when kb_check quotes requirement_statement_unverified, or when a request conflicts with a recorded requirement or ADR. Covers reading firmness and origin, recording a person's rule as firm with origin.ref, superseding with a Why this changed section, the kb_compile_intent unresolved/reviewCandidates/conflictReviews loop, asking before overriding a firm rule, and putting decisions to the person as one numbered kibi signoff --questions view."
|
|
5
|
-
version: 1.
|
|
5
|
+
version: 1.5.0
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -115,7 +115,12 @@ again until none is open, then record each rule with their words in
|
|
|
115
115
|
`origin.ref`. Fields and outputs: `resources/signoff-views.md`.
|
|
116
116
|
|
|
117
117
|
Never invent words for `origin.ref`, never set `approved_by` yourself, and
|
|
118
|
-
mark your own picks `default` and guesses `exploratory`.
|
|
118
|
+
mark your own picks `default` and guesses `exploratory`. Once the person has
|
|
119
|
+
answered, recording their answer (their name in `approved_by` or a
|
|
120
|
+
`*_waiver_approved_by` field, their words in `origin.ref` or `approval_ref`)
|
|
121
|
+
is yours to do: put it on the branch of the change it approves and push it to
|
|
122
|
+
that pull request, never to a separate one. Ask before you open or merge the
|
|
123
|
+
pull request, so the answer lands in it. Payload shapes,
|
|
119
124
|
refusal messages and the `kb_compile_intent` review loop are in
|
|
120
125
|
`resources/decision-records.md`.
|
|
121
126
|
|
|
@@ -51,7 +51,9 @@ writes and opens the page; `--format json` prints the view.
|
|
|
51
51
|
The person answers by number ("1 yes, 2 exploratory, 3 reword: ..."). Copy
|
|
52
52
|
each answer into `answer`, render again, and record the rules only once every
|
|
53
53
|
question is answered. An answer is the person's words: quote it in
|
|
54
|
-
`origin.ref`; a view itself is never an approval.
|
|
54
|
+
`origin.ref`; a view itself is never an approval. Record the answers on the
|
|
55
|
+
branch of the change they approve and push them to its pull request, never to
|
|
56
|
+
a separate one.
|
|
55
57
|
|
|
56
58
|
## Summary contents
|
|
57
59
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: kibi-usage
|
|
3
3
|
name: Kibi Usage
|
|
4
4
|
description: Use Kibi's source-first, exact-Git, migration-aware, proof-aware operations safely across MCP or the trusted local CLI, including partial completion repair.
|
|
5
|
-
version: 2.
|
|
5
|
+
version: 2.37.0
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -372,6 +372,14 @@ human sets `approved_by`; `kb_check` flags approvals an agent recorded without
|
|
|
372
372
|
corroboration. Never fill in an approval yourself. Record why a requirement
|
|
373
373
|
exists in `rationale`, or link the ADR that explains it.
|
|
374
374
|
|
|
375
|
+
A signoff belongs to the change it approves. Ask for it before you open or
|
|
376
|
+
merge the pull request, and when the person answers, record their answer
|
|
377
|
+
(`approved_by` or a `*_waiver_approved_by` field set to them, their words in
|
|
378
|
+
`origin.ref` or `approval_ref`) on the same branch and push it to the same pull
|
|
379
|
+
request. Writing down an answer the person gave is not approving it yourself.
|
|
380
|
+
Never open a separate pull request only to carry a signoff, firmness or waiver
|
|
381
|
+
approval.
|
|
382
|
+
|
|
375
383
|
## Decision firmness
|
|
376
384
|
|
|
377
385
|
Requirements and ADRs carry `firmness`, which says what you may do with them.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kibi-cursor",
|
|
3
|
-
"version": "2.10.
|
|
3
|
+
"version": "2.10.1",
|
|
4
4
|
"description": "Kibi Cursor plugin - thin adapter for Cursor MCP integration and editor hooks",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
}
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"kibi-agent-core": "^0.
|
|
62
|
+
"kibi-agent-core": "^0.11.0"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
|
65
65
|
"@types/node": "latest",
|
package/skills/.canon-hash.json
CHANGED
|
@@ -4,11 +4,11 @@
|
|
|
4
4
|
"kibi-bootstrap/resources/branch-lifecycle.md": "c854264ce888439140883a3fc636db5e522f020dd27b30a5c1ecc4105b64ed13",
|
|
5
5
|
"kibi-bootstrap/resources/operation-access.md": "b5a6a59e72d800c376e7fad79132897623c32a0ce152a1e8d73f9628b444db51",
|
|
6
6
|
"kibi-bootstrap/resources/source-authoring.md": "bf296e62f69474e01797d6cb9469bf624551dca834dd188abb6e705bd96fa586",
|
|
7
|
-
"kibi-commit-review/SKILL.md": "
|
|
7
|
+
"kibi-commit-review/SKILL.md": "bec768ad3e4cd4e782e9e13360b69bcd40a0964b305909818115d7f9e8d282d9",
|
|
8
8
|
"kibi-commit-review/resources/staged-gate.md": "37f750f327bb9202c1f30989763f4f1205b906cf672318ca50887d7984bc3e08",
|
|
9
|
-
"kibi-decisions/SKILL.md": "
|
|
9
|
+
"kibi-decisions/SKILL.md": "d91f784410251095e9d881bce751728cc4596858a518fb24f5e5d38c940bab50",
|
|
10
10
|
"kibi-decisions/resources/decision-records.md": "b201e619c48daf6ebe5989991a96f6c0573adb6c37abf814b9d34b7a1cd423c6",
|
|
11
|
-
"kibi-decisions/resources/signoff-views.md": "
|
|
11
|
+
"kibi-decisions/resources/signoff-views.md": "84eb2b7123e54047205b84af6fbf60c910ebcaaf98023e5812f3de9b65a4871c",
|
|
12
12
|
"kibi-freshness/SKILL.md": "b5c4f24bebdb5b4e0d04c2fa1176fc33ace35334b0c0b6ca943d6f445dc9b69e",
|
|
13
13
|
"kibi-freshness/resources/branch-lifecycle.md": "ebc01b19fe3dca8df5fc0175978963f6f1204f71f7c805cb2a5fb1b277ac78e4",
|
|
14
14
|
"kibi-freshness/resources/operation-access.md": "4e1db9294ee540cd29b8b3a2532a81e7894d5b4228b39e99ba48b37212f489f3",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"kibi-traceability/resources/operation-access.md": "39f7972ab7f4ae7479e78f7072bb50e8e6c4cdf4f857425f69d2522d37db437c",
|
|
19
19
|
"kibi-traceability/resources/source-authoring.md": "408c6ee2bef1b84e0194c0538ef929c26a0a617e631b2234247388140dbbdd08",
|
|
20
20
|
"kibi-traceability/resources/traceability.md": "38c290a0bc71bd1692e115f22694743946e2f69630e134acfd43cee5f613fb88",
|
|
21
|
-
"kibi-usage/SKILL.md": "
|
|
21
|
+
"kibi-usage/SKILL.md": "24c7148c78501a1fa8d9374e96c9a2c5503d04347c186c958cbd768cd67abd88",
|
|
22
22
|
"kibi-usage/resources/branch-lifecycle.md": "f1bf359e9826e83c548f3cd0287f8175a62456527b0132b06b3f9f74aa59b7d6",
|
|
23
23
|
"kibi-usage/resources/fact-lanes.md": "7d487ffb794f6a7c32afabc7756a265a258b072ca83510ddb40d275863d44648",
|
|
24
24
|
"kibi-usage/resources/kb-improvement.md": "a8408fce27342bdce6415a6718599e53fe00bb33aa1fd3dc42353ec6f61adcd7",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: kibi-commit-review
|
|
3
3
|
name: kibi-commit-review
|
|
4
4
|
description: "Use when kibi check --staged or the Kibi pre-commit hook blocks a commit (kibi_impact_evidence_missing, symbols_manifest_stale, symbol_granularity_violation, symbol-coverage, kibi check-generated drift, Staged impact review failed), or when preparing a commit or pull-request impact review. Covers reading the per-file Detail lines, authoring .kb/symbols.yaml symbol entries through kb_upsert, staging the tracked Kibi evidence with git add (symbol coordinates are derived and never staged), kb_prepare_impact_review for a staged or diff scope, the kibi signoff requirements summary to show before a commit, and how merge commits and migration renames are judged."
|
|
5
|
-
version: 1.
|
|
5
|
+
version: 1.4.0
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -91,7 +91,11 @@ apps); never attach the `.html` as a file, which chat apps show as raw source;
|
|
|
91
91
|
past 15 requirements the Markdown stops and only the page lists them all.
|
|
92
92
|
Host details: `kibi-decisions`, `resources/signoff-views.md`. `--no-proof` skips the proof lookup, which reads coverage and is slow
|
|
93
93
|
on a large knowledge base. The summary is not an approval: never set
|
|
94
|
-
`approved_by` or `origin.ref` from it.
|
|
94
|
+
`approved_by` or `origin.ref` from it. Show it before you open or merge the
|
|
95
|
+
pull request. When the person answers, record their answer in the same
|
|
96
|
+
change (their name in `approved_by`, their words in `origin.ref` or
|
|
97
|
+
`approval_ref`) and push it to the same pull request; never move a signoff,
|
|
98
|
+
firmness or waiver approval into a separate pull request.
|
|
95
99
|
|
|
96
100
|
## Impact reviews
|
|
97
101
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: kibi-decisions
|
|
3
3
|
name: kibi-decisions
|
|
4
4
|
description: "Use when the person states a rule or decision (must, never, always, from now on, we decided), when a Kibi hook asks to confirm or warns about an edit to code that implements a firm requirement, when the Stop hook says source files changed but nothing was recorded, when kb_check quotes requirement_statement_unverified, or when a request conflicts with a recorded requirement or ADR. Covers reading firmness and origin, recording a person's rule as firm with origin.ref, superseding with a Why this changed section, the kb_compile_intent unresolved/reviewCandidates/conflictReviews loop, asking before overriding a firm rule, and putting decisions to the person as one numbered kibi signoff --questions view."
|
|
5
|
-
version: 1.
|
|
5
|
+
version: 1.5.0
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -115,7 +115,12 @@ again until none is open, then record each rule with their words in
|
|
|
115
115
|
`origin.ref`. Fields and outputs: `resources/signoff-views.md`.
|
|
116
116
|
|
|
117
117
|
Never invent words for `origin.ref`, never set `approved_by` yourself, and
|
|
118
|
-
mark your own picks `default` and guesses `exploratory`.
|
|
118
|
+
mark your own picks `default` and guesses `exploratory`. Once the person has
|
|
119
|
+
answered, recording their answer (their name in `approved_by` or a
|
|
120
|
+
`*_waiver_approved_by` field, their words in `origin.ref` or `approval_ref`)
|
|
121
|
+
is yours to do: put it on the branch of the change it approves and push it to
|
|
122
|
+
that pull request, never to a separate one. Ask before you open or merge the
|
|
123
|
+
pull request, so the answer lands in it. Payload shapes,
|
|
119
124
|
refusal messages and the `kb_compile_intent` review loop are in
|
|
120
125
|
`resources/decision-records.md`.
|
|
121
126
|
|
|
@@ -51,7 +51,9 @@ writes and opens the page; `--format json` prints the view.
|
|
|
51
51
|
The person answers by number ("1 yes, 2 exploratory, 3 reword: ..."). Copy
|
|
52
52
|
each answer into `answer`, render again, and record the rules only once every
|
|
53
53
|
question is answered. An answer is the person's words: quote it in
|
|
54
|
-
`origin.ref`; a view itself is never an approval.
|
|
54
|
+
`origin.ref`; a view itself is never an approval. Record the answers on the
|
|
55
|
+
branch of the change they approve and push them to its pull request, never to
|
|
56
|
+
a separate one.
|
|
55
57
|
|
|
56
58
|
## Summary contents
|
|
57
59
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
id: kibi-usage
|
|
3
3
|
name: Kibi Usage
|
|
4
4
|
description: Use Kibi's source-first, exact-Git, migration-aware, proof-aware operations safely across MCP or the trusted local CLI, including partial completion repair.
|
|
5
|
-
version: 2.
|
|
5
|
+
version: 2.37.0
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -372,6 +372,14 @@ human sets `approved_by`; `kb_check` flags approvals an agent recorded without
|
|
|
372
372
|
corroboration. Never fill in an approval yourself. Record why a requirement
|
|
373
373
|
exists in `rationale`, or link the ADR that explains it.
|
|
374
374
|
|
|
375
|
+
A signoff belongs to the change it approves. Ask for it before you open or
|
|
376
|
+
merge the pull request, and when the person answers, record their answer
|
|
377
|
+
(`approved_by` or a `*_waiver_approved_by` field set to them, their words in
|
|
378
|
+
`origin.ref` or `approval_ref`) on the same branch and push it to the same pull
|
|
379
|
+
request. Writing down an answer the person gave is not approving it yourself.
|
|
380
|
+
Never open a separate pull request only to carry a signoff, firmness or waiver
|
|
381
|
+
approval.
|
|
382
|
+
|
|
375
383
|
## Decision firmness
|
|
376
384
|
|
|
377
385
|
Requirements and ADRs carry `firmness`, which says what you may do with them.
|