kibi-runtime 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -19154,9 +19154,25 @@ function bootstrapEmptyKbSnapshotId(input) {
|
|
|
19154
19154
|
sourceHashes: input.sourceHashes
|
|
19155
19155
|
})).digest("hex")}`;
|
|
19156
19156
|
}
|
|
19157
|
-
var BOOTSTRAP_PROVIDER_ORDER;
|
|
19157
|
+
var KNOWLEDGE_SOURCE_KINDS, KNOWLEDGE_SOURCE_AUTHORITIES, BOOTSTRAP_PROVIDER_ORDER;
|
|
19158
19158
|
var init_types = __esm(() => {
|
|
19159
19159
|
init_shared();
|
|
19160
|
+
KNOWLEDGE_SOURCE_KINDS = [
|
|
19161
|
+
"issue_tracker",
|
|
19162
|
+
"wiki",
|
|
19163
|
+
"specification",
|
|
19164
|
+
"design",
|
|
19165
|
+
"decision_log",
|
|
19166
|
+
"support",
|
|
19167
|
+
"chat",
|
|
19168
|
+
"repository_docs",
|
|
19169
|
+
"other"
|
|
19170
|
+
];
|
|
19171
|
+
KNOWLEDGE_SOURCE_AUTHORITIES = [
|
|
19172
|
+
"authoritative",
|
|
19173
|
+
"supporting",
|
|
19174
|
+
"stale"
|
|
19175
|
+
];
|
|
19160
19176
|
BOOTSTRAP_PROVIDER_ORDER = [
|
|
19161
19177
|
"typed_kibi_docs",
|
|
19162
19178
|
"generic_repo_docs",
|
|
@@ -30977,6 +30993,8 @@ function parseTelemetryUsageLog(contents) {
|
|
|
30977
30993
|
if (!isRecord9(parsed)) {
|
|
30978
30994
|
throw new Error(`Failed to parse .kb/usage.log line ${index + 1}: expected object`);
|
|
30979
30995
|
}
|
|
30996
|
+
if (parsed.interface === "hook")
|
|
30997
|
+
continue;
|
|
30980
30998
|
events.push(parsed);
|
|
30981
30999
|
}
|
|
30982
31000
|
return events;
|
|
@@ -48479,7 +48497,7 @@ async function refreshUnlocked(symbolId, context, options2 = {}) {
|
|
|
48479
48497
|
}
|
|
48480
48498
|
const sourceFile = typeof entry.sourceFile === "string" ? entry.sourceFile : "";
|
|
48481
48499
|
const title = typeof entry.title === "string" ? entry.title : "";
|
|
48482
|
-
const [enriched] = await enrichSymbolCoordinates([{ ...entry, id: symbolId, title, sourceFile }], context.workspaceRoot);
|
|
48500
|
+
const [enriched] = await enrichSymbolCoordinates([{ ...entry, id: symbolId, title, sourceFile }], context.workspaceRoot, { allowPythonDecoratorCoordinates: true });
|
|
48483
48501
|
let next = coordinate(enriched);
|
|
48484
48502
|
let sourceText = next === null ? sourceTextFor(sourceFile, context.workspaceRoot) : null;
|
|
48485
48503
|
if (next === null && isCoarseGranularityReason(entry.granularity_reason) && sourceText !== null) {
|
|
@@ -53652,7 +53670,9 @@ async function inspectCoordinateRepairs(symbols, workspaceRoot) {
|
|
|
53652
53670
|
...typeof symbol.granularity_reason === "string" ? { granularity_reason: symbol.granularity_reason } : {}
|
|
53653
53671
|
};
|
|
53654
53672
|
});
|
|
53655
|
-
const enriched = await enrichSymbolCoordinates(entries, workspaceRoot
|
|
53673
|
+
const enriched = await enrichSymbolCoordinates(entries, workspaceRoot, {
|
|
53674
|
+
allowPythonDecoratorCoordinates: true
|
|
53675
|
+
});
|
|
53656
53676
|
return new Map(entries.map((entry, index) => {
|
|
53657
53677
|
const sourceFile = entry.sourceFile ?? null;
|
|
53658
53678
|
let source = null;
|
|
@@ -61883,12 +61903,94 @@ async function discoverBootstrap(context) {
|
|
|
61883
61903
|
};
|
|
61884
61904
|
}
|
|
61885
61905
|
|
|
61906
|
+
// ../cli/dist/operations/bootstrap/intent-claims.js
|
|
61907
|
+
var AUTHORITY_CONFIDENCE = {
|
|
61908
|
+
authoritative: 0.9,
|
|
61909
|
+
supporting: 0.82
|
|
61910
|
+
};
|
|
61911
|
+
function citation(source, claim) {
|
|
61912
|
+
return [
|
|
61913
|
+
`intent_claim:${source.id}:${claim.reference}`,
|
|
61914
|
+
`knowledge_source:${source.kind}:${source.locator}`,
|
|
61915
|
+
`source_authority:${source.authority}`,
|
|
61916
|
+
...source.connector ? [`connector:${source.connector}`] : []
|
|
61917
|
+
];
|
|
61918
|
+
}
|
|
61919
|
+
function buildIntentClaimCandidates(declared, existingIds, minConfidence) {
|
|
61920
|
+
const sources = new Map((declared.knowledgeSources ?? []).map((source) => [source.id, source]));
|
|
61921
|
+
const candidates = [];
|
|
61922
|
+
const sourceOnlySignals = [];
|
|
61923
|
+
const suppressed = [];
|
|
61924
|
+
const diagnostics = [];
|
|
61925
|
+
for (const claim of declared.intentClaims ?? []) {
|
|
61926
|
+
const source = sources.get(claim.sourceId);
|
|
61927
|
+
if (!source) {
|
|
61928
|
+
diagnostics.push(`Intent claim cites an undeclared knowledge source "${claim.sourceId}" (${claim.reference}); declare it in knowledgeSources or drop the claim.`);
|
|
61929
|
+
continue;
|
|
61930
|
+
}
|
|
61931
|
+
if (source.authority === "stale") {
|
|
61932
|
+
suppressed.push({
|
|
61933
|
+
candidateId: "",
|
|
61934
|
+
reason: "stale_knowledge_source",
|
|
61935
|
+
sourcePath: claim.reference,
|
|
61936
|
+
entityType: "req",
|
|
61937
|
+
statement: claim.statement,
|
|
61938
|
+
sourceId: source.id
|
|
61939
|
+
});
|
|
61940
|
+
continue;
|
|
61941
|
+
}
|
|
61942
|
+
const confidence = AUTHORITY_CONFIDENCE[source.authority];
|
|
61943
|
+
const evidence = citation(source, claim);
|
|
61944
|
+
const provenance = `${source.id}:${claim.reference}`;
|
|
61945
|
+
const modeled = claimFor(claim.statement, `knowledge-source:${source.id}`, confidence, provenance);
|
|
61946
|
+
const writeSet = modeled ? buildStrictWriteSet({ claim: modeled, statement: claim.statement }) : null;
|
|
61947
|
+
if (writeSet?.isStrict && confidence >= minConfidence && !existingIds.has(writeSet.req.id)) {
|
|
61948
|
+
candidates.push({
|
|
61949
|
+
candidateId: `claim:${source.id}:${writeSet.req.id.toLowerCase()}`,
|
|
61950
|
+
entityType: "req",
|
|
61951
|
+
title: claim.statement,
|
|
61952
|
+
sourceKind: "intent_claim",
|
|
61953
|
+
sourcePath: claim.reference,
|
|
61954
|
+
confidence,
|
|
61955
|
+
confidenceBand: confidenceBand(confidence),
|
|
61956
|
+
evidence,
|
|
61957
|
+
relationships: writeSet.relationships.map(({ type, from, to }) => ({
|
|
61958
|
+
type,
|
|
61959
|
+
from,
|
|
61960
|
+
to
|
|
61961
|
+
})),
|
|
61962
|
+
applyPlan: strictPlan(writeSet)
|
|
61963
|
+
});
|
|
61964
|
+
continue;
|
|
61965
|
+
}
|
|
61966
|
+
if (writeSet?.isStrict && existingIds.has(writeSet.req.id)) {
|
|
61967
|
+
suppressed.push({
|
|
61968
|
+
candidateId: `claim:${source.id}:${writeSet.req.id.toLowerCase()}`,
|
|
61969
|
+
reason: "entity_exists",
|
|
61970
|
+
sourcePath: claim.reference,
|
|
61971
|
+
entityType: "req"
|
|
61972
|
+
});
|
|
61973
|
+
continue;
|
|
61974
|
+
}
|
|
61975
|
+
sourceOnlySignals.push({
|
|
61976
|
+
kind: "req",
|
|
61977
|
+
title: `Author requirement from ${source.title} ${claim.reference}: ${claim.statement}`,
|
|
61978
|
+
sourcePath: claim.reference,
|
|
61979
|
+
confidence,
|
|
61980
|
+
evidence
|
|
61981
|
+
});
|
|
61982
|
+
}
|
|
61983
|
+
return { candidates, sourceOnlySignals, suppressed, diagnostics };
|
|
61984
|
+
}
|
|
61985
|
+
|
|
61886
61986
|
// ../cli/dist/operations/bootstrap/guidance.js
|
|
61887
61987
|
import path26 from "node:path";
|
|
61888
61988
|
|
|
61889
61989
|
// ../cli/dist/operations/bootstrap/guidance-actions.js
|
|
61890
61990
|
import path25 from "node:path";
|
|
61891
61991
|
function relative2(root, target) {
|
|
61992
|
+
if (!path25.isAbsolute(target))
|
|
61993
|
+
return target;
|
|
61892
61994
|
const value = path25.relative(root, target);
|
|
61893
61995
|
return value.startsWith("..") || path25.isAbsolute(value) ? target.split(path25.sep).join("/") : value.split(path25.sep).join("/");
|
|
61894
61996
|
}
|
|
@@ -61958,6 +62060,8 @@ function buildActions(root, activation, declared, candidates, signals) {
|
|
|
61958
62060
|
|
|
61959
62061
|
// ../cli/dist/operations/bootstrap/guidance.js
|
|
61960
62062
|
function relative3(root, target) {
|
|
62063
|
+
if (!path26.isAbsolute(target))
|
|
62064
|
+
return target;
|
|
61961
62065
|
const value = path26.relative(root, target);
|
|
61962
62066
|
return value.startsWith("..") || path26.isAbsolute(value) ? target.split(path26.sep).join("/") : value.split(path26.sep).join("/");
|
|
61963
62067
|
}
|
|
@@ -61979,6 +62083,8 @@ function prompt(root, activation, declared, candidates, signals, warnings) {
|
|
|
61979
62083
|
bullets.push(`- Summary: ${declared.projectSummary}`);
|
|
61980
62084
|
if (declared.sourceOfTruthPaths.length > 0)
|
|
61981
62085
|
bullets.push(`- Source of truth: ${summary2(declared.sourceOfTruthPaths)}.`);
|
|
62086
|
+
if (declared.knowledgeSources)
|
|
62087
|
+
bullets.push(`- Knowledge sources: ${summary2(declared.knowledgeSources.map((source) => `${source.title} (${source.authority})`))}; ${declared.intentClaims?.length ?? 0} cited intent claim(s).`);
|
|
61982
62088
|
if (candidates.length > 0) {
|
|
61983
62089
|
const formatted = Object.entries(counts(candidates)).sort(([left], [right]) => left.localeCompare(right)).map(([type, count]) => `${type} ${count}`).join(", ");
|
|
61984
62090
|
bullets.push(`- Safe candidates: ${candidates.length} (${formatted}).`);
|
|
@@ -62024,7 +62130,7 @@ function confidence(activation, declared, candidates, signals, promptBlock) {
|
|
|
62024
62130
|
vendored_blocked: -0.25
|
|
62025
62131
|
}[activation.activationMode];
|
|
62026
62132
|
reasons.push(`${activation.activationMode} determined the bootstrap posture.`);
|
|
62027
|
-
if (declared.projectSummary || declared.sourceOfTruthPaths.length + declared.sourceOfTruthNotes.length + declared.priorityRoots.length + declared.verificationAnchors.length > 0) {
|
|
62133
|
+
if (declared.projectSummary || declared.sourceOfTruthPaths.length + declared.sourceOfTruthNotes.length + declared.priorityRoots.length + declared.verificationAnchors.length + (declared.knowledgeSources?.length ?? 0) > 0) {
|
|
62028
62134
|
score += 0.08;
|
|
62029
62135
|
reasons.push("Declared bootstrap context grounds the output.");
|
|
62030
62136
|
} else
|
|
@@ -62065,14 +62171,65 @@ function strings(values) {
|
|
|
62065
62171
|
...new Set((values ?? []).map((value) => value.trim()).filter(Boolean))
|
|
62066
62172
|
];
|
|
62067
62173
|
}
|
|
62174
|
+
function knowledgeSources(values) {
|
|
62175
|
+
const seen = new Set;
|
|
62176
|
+
const result = [];
|
|
62177
|
+
for (const value of values ?? []) {
|
|
62178
|
+
const id = value.id?.trim();
|
|
62179
|
+
const title = value.title?.trim();
|
|
62180
|
+
const locator = value.locator?.trim();
|
|
62181
|
+
if (!id || !title || !locator || seen.has(id) || !KNOWLEDGE_SOURCE_KINDS.includes(value.kind) || !KNOWLEDGE_SOURCE_AUTHORITIES.includes(value.authority))
|
|
62182
|
+
continue;
|
|
62183
|
+
seen.add(id);
|
|
62184
|
+
const connector = value.connector?.trim();
|
|
62185
|
+
const notes = value.notes?.trim();
|
|
62186
|
+
result.push({
|
|
62187
|
+
id,
|
|
62188
|
+
kind: value.kind,
|
|
62189
|
+
title,
|
|
62190
|
+
locator,
|
|
62191
|
+
authority: value.authority,
|
|
62192
|
+
...connector ? { connector } : {},
|
|
62193
|
+
...notes ? { notes } : {}
|
|
62194
|
+
});
|
|
62195
|
+
}
|
|
62196
|
+
return result;
|
|
62197
|
+
}
|
|
62198
|
+
function intentClaims(values) {
|
|
62199
|
+
const seen = new Set;
|
|
62200
|
+
const result = [];
|
|
62201
|
+
for (const value of values ?? []) {
|
|
62202
|
+
const statement = value.statement?.trim().replace(/\s+/g, " ");
|
|
62203
|
+
const sourceId = value.sourceId?.trim();
|
|
62204
|
+
const reference = value.reference?.trim();
|
|
62205
|
+
if (!statement || !sourceId || !reference)
|
|
62206
|
+
continue;
|
|
62207
|
+
const key = `${sourceId}\x00${reference}\x00${statement}`;
|
|
62208
|
+
if (seen.has(key))
|
|
62209
|
+
continue;
|
|
62210
|
+
seen.add(key);
|
|
62211
|
+
const excerpt = value.excerpt?.trim();
|
|
62212
|
+
result.push({
|
|
62213
|
+
statement,
|
|
62214
|
+
sourceId,
|
|
62215
|
+
reference,
|
|
62216
|
+
...excerpt ? { excerpt } : {}
|
|
62217
|
+
});
|
|
62218
|
+
}
|
|
62219
|
+
return result;
|
|
62220
|
+
}
|
|
62068
62221
|
function normalizeBootstrapContext(input) {
|
|
62069
62222
|
const projectSummary = input?.projectSummary?.trim();
|
|
62223
|
+
const sources = knowledgeSources(input?.knowledgeSources);
|
|
62224
|
+
const claims = intentClaims(input?.intentClaims);
|
|
62070
62225
|
return {
|
|
62071
62226
|
...projectSummary ? { projectSummary } : {},
|
|
62072
62227
|
sourceOfTruthPaths: strings(input?.sourceOfTruthPaths),
|
|
62073
62228
|
sourceOfTruthNotes: strings(input?.sourceOfTruthNotes),
|
|
62074
62229
|
priorityRoots: strings(input?.priorityRoots),
|
|
62075
|
-
verificationAnchors: strings(input?.verificationAnchors)
|
|
62230
|
+
verificationAnchors: strings(input?.verificationAnchors),
|
|
62231
|
+
...sources.length > 0 ? { knowledgeSources: sources } : {},
|
|
62232
|
+
...claims.length > 0 ? { intentClaims: claims } : {}
|
|
62076
62233
|
};
|
|
62077
62234
|
}
|
|
62078
62235
|
function payoff(candidates) {
|
|
@@ -62124,6 +62281,8 @@ function presentBootstrap(input) {
|
|
|
62124
62281
|
if (status === "needs_context") {
|
|
62125
62282
|
if (!declaredContext.projectSummary)
|
|
62126
62283
|
contextQuestions.push("What is the one-sentence purpose of this repository?");
|
|
62284
|
+
if (!declaredContext.knowledgeSources)
|
|
62285
|
+
contextQuestions.push("Which knowledge sources outside the code (issue trackers, wikis, specs, decision logs) describe product intent, and which of them are authoritative?");
|
|
62127
62286
|
if (declaredContext.sourceOfTruthPaths.length === 0)
|
|
62128
62287
|
contextQuestions.push("Which repository paths are authoritative for product intent?");
|
|
62129
62288
|
if (input.sourceOnlySignals.length > 0)
|
|
@@ -62136,7 +62295,8 @@ function presentBootstrap(input) {
|
|
|
62136
62295
|
const diagnostics = [
|
|
62137
62296
|
...input.migrationWarning ? [input.migrationWarning] : [],
|
|
62138
62297
|
...input.discoverySummary.scanWarnings,
|
|
62139
|
-
...bindingDiagnostics
|
|
62298
|
+
...bindingDiagnostics,
|
|
62299
|
+
...strings(input.contextDiagnostics)
|
|
62140
62300
|
];
|
|
62141
62301
|
const planBody = {
|
|
62142
62302
|
version: "kibi.bootstrap-plan.v1",
|
|
@@ -62328,8 +62488,14 @@ async function executePlanBootstrap(args, context) {
|
|
|
62328
62488
|
]);
|
|
62329
62489
|
const bound = await expectedSnapshots(context, discovery.evidence.map((evidence) => evidence.relativePath).filter((value) => Boolean(value)));
|
|
62330
62490
|
const built = discovery.activation.allowCandidateGeneration ? buildBootstrapCandidates(discovery.evidence, existingIds, minConfidence, includeGenericMarkdown) : { candidates: [], sourceOnlySignals: [] };
|
|
62331
|
-
const
|
|
62332
|
-
|
|
62491
|
+
const claimed = discovery.activation.allowCandidateGeneration ? buildIntentClaimCandidates(normalizeBootstrapContext(args.bootstrapContext), existingIds, minConfidence) : {
|
|
62492
|
+
candidates: [],
|
|
62493
|
+
sourceOnlySignals: [],
|
|
62494
|
+
suppressed: [],
|
|
62495
|
+
diagnostics: []
|
|
62496
|
+
};
|
|
62497
|
+
const filteredSignals = filterSourceOnlySignals([...built.sourceOnlySignals, ...claimed.sourceOnlySignals], args.entityTypes);
|
|
62498
|
+
const selected = selectBootstrapCandidates([...built.candidates, ...claimed.candidates].filter((candidate) => candidate.confidence >= minConfidence), existingIds, args.entityTypes, maxCandidates);
|
|
62333
62499
|
const ignored = discovery.ignoredSources.map((sourcePath) => ({
|
|
62334
62500
|
candidateId: "",
|
|
62335
62501
|
reason: "ignored_source",
|
|
@@ -62345,17 +62511,23 @@ async function executePlanBootstrap(args, context) {
|
|
|
62345
62511
|
...args.bootstrapContext ? { bootstrapContext: args.bootstrapContext } : {},
|
|
62346
62512
|
candidates: selected.candidates,
|
|
62347
62513
|
sourceOnlySignals: filteredSignals,
|
|
62348
|
-
suppressedCandidates: [
|
|
62514
|
+
suppressedCandidates: [
|
|
62515
|
+
...selected.suppressed,
|
|
62516
|
+
...claimed.suppressed,
|
|
62517
|
+
...ignored
|
|
62518
|
+
],
|
|
62349
62519
|
expected,
|
|
62350
|
-
bindingDiagnostics
|
|
62520
|
+
bindingDiagnostics,
|
|
62521
|
+
contextDiagnostics: claimed.diagnostics
|
|
62351
62522
|
});
|
|
62352
62523
|
}
|
|
62353
62524
|
|
|
62354
62525
|
// ../cli/dist/public/operations/specs/bootstrap.js
|
|
62526
|
+
init_types();
|
|
62355
62527
|
var planBootstrapSpec = {
|
|
62356
62528
|
name: "kb_plan_bootstrap",
|
|
62357
62529
|
cliName: "plan-bootstrap",
|
|
62358
|
-
description: "Generate a deterministic, snapshot-bound kibi.bootstrap-plan.v1 for repository onboarding. Read-only analysis returns evidence, bounded context questions, exact dependency-ordered actions, a canonical plan hash, and no mutation side effects.",
|
|
62530
|
+
description: "Generate a deterministic, snapshot-bound kibi.bootstrap-plan.v1 for repository onboarding. Read-only analysis of the repository plus any declared knowledge sources and cited intent claims returns evidence, bounded context questions, exact dependency-ordered actions, a canonical plan hash, and no mutation side effects.",
|
|
62359
62531
|
businessInputSchema: {
|
|
62360
62532
|
type: "object",
|
|
62361
62533
|
properties: {
|
|
@@ -62413,6 +62585,70 @@ var planBootstrapSpec = {
|
|
|
62413
62585
|
type: "array",
|
|
62414
62586
|
items: { type: "string" },
|
|
62415
62587
|
description: "Optional verification commands, documents, or checkpoints to reference in the output."
|
|
62588
|
+
},
|
|
62589
|
+
knowledgeSources: {
|
|
62590
|
+
type: "array",
|
|
62591
|
+
maxItems: 50,
|
|
62592
|
+
description: "Knowledge sources outside the code that the human confirmed during the bootstrap interview (issue trackers, wikis, specs, decision logs). Kibi never contacts them; the agent reads them through its own connectors and cites them from intentClaims. Bound into the plan hash.",
|
|
62593
|
+
items: {
|
|
62594
|
+
type: "object",
|
|
62595
|
+
required: ["id", "kind", "title", "locator", "authority"],
|
|
62596
|
+
additionalProperties: false,
|
|
62597
|
+
properties: {
|
|
62598
|
+
id: {
|
|
62599
|
+
type: "string",
|
|
62600
|
+
pattern: "^[a-z0-9][a-z0-9-]*$",
|
|
62601
|
+
description: "Stable kebab-case handle that intentClaims cite, for example jira-payments."
|
|
62602
|
+
},
|
|
62603
|
+
kind: { type: "string", enum: [...KNOWLEDGE_SOURCE_KINDS] },
|
|
62604
|
+
title: { type: "string", minLength: 1 },
|
|
62605
|
+
locator: {
|
|
62606
|
+
type: "string",
|
|
62607
|
+
minLength: 1,
|
|
62608
|
+
description: "Where the source lives: a URL, project key, space name, or repo-relative path."
|
|
62609
|
+
},
|
|
62610
|
+
authority: {
|
|
62611
|
+
type: "string",
|
|
62612
|
+
enum: [...KNOWLEDGE_SOURCE_AUTHORITIES],
|
|
62613
|
+
description: "The human's call: authoritative claims become higher-confidence candidates, supporting claims lower ones, and stale sources are cited but never produce candidates."
|
|
62614
|
+
},
|
|
62615
|
+
connector: {
|
|
62616
|
+
type: "string",
|
|
62617
|
+
description: "Optional name of the MCP server or tool the agent used to read the source."
|
|
62618
|
+
},
|
|
62619
|
+
notes: { type: "string" }
|
|
62620
|
+
}
|
|
62621
|
+
}
|
|
62622
|
+
},
|
|
62623
|
+
intentClaims: {
|
|
62624
|
+
type: "array",
|
|
62625
|
+
maxItems: 200,
|
|
62626
|
+
description: "Statements of product intent the agent harvested from knowledgeSources, each citing its source. Normative claims the strict modeler can ground become cited req candidates; the rest become explicit authoring follow-ups. Bound into the plan hash.",
|
|
62627
|
+
items: {
|
|
62628
|
+
type: "object",
|
|
62629
|
+
required: ["statement", "sourceId", "reference"],
|
|
62630
|
+
additionalProperties: false,
|
|
62631
|
+
properties: {
|
|
62632
|
+
statement: {
|
|
62633
|
+
type: "string",
|
|
62634
|
+
minLength: 1,
|
|
62635
|
+
description: "One normative statement in the source's meaning, for example 'Refunds must not exceed the original charge.'"
|
|
62636
|
+
},
|
|
62637
|
+
sourceId: {
|
|
62638
|
+
type: "string",
|
|
62639
|
+
description: "The id of a declared knowledge source."
|
|
62640
|
+
},
|
|
62641
|
+
reference: {
|
|
62642
|
+
type: "string",
|
|
62643
|
+
minLength: 1,
|
|
62644
|
+
description: "Exact citation inside the source: a ticket key, page URL, or section anchor."
|
|
62645
|
+
},
|
|
62646
|
+
excerpt: {
|
|
62647
|
+
type: "string",
|
|
62648
|
+
description: "Optional short quote supporting the claim."
|
|
62649
|
+
}
|
|
62650
|
+
}
|
|
62651
|
+
}
|
|
62416
62652
|
}
|
|
62417
62653
|
}
|
|
62418
62654
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
id: kibi-bootstrap
|
|
3
3
|
name: kibi-bootstrap
|
|
4
|
-
description: Bootstrap Kibi from the current Git checkout with
|
|
5
|
-
version: 3.
|
|
4
|
+
description: Bootstrap Kibi from the current Git checkout and the project's existing knowledge sources, with a source interview, cited intent claims, preview approval, source-first writes, and repair-safe completion.
|
|
5
|
+
version: 3.1.0
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -18,20 +18,56 @@ resources:
|
|
|
18
18
|
## Goal
|
|
19
19
|
|
|
20
20
|
Seed branch-local Kibi knowledge for an attached but thin repository without
|
|
21
|
-
creating a parallel human-maintained ticket system.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
creating a parallel human-maintained ticket system. Code shows what the
|
|
22
|
+
system does, not why; intent usually lives elsewhere (issue trackers, wikis,
|
|
23
|
+
specs, decision logs). Lead a short interview to find those sources, harvest
|
|
24
|
+
cited intent from them, and let the planner consolidate it with repository
|
|
25
|
+
evidence. Agents own reading and translation; humans name the sources,
|
|
26
|
+
judge their authority, and resolve genuine ambiguity. A seeded repository
|
|
27
|
+
hands off to the normal Kibi workflow.
|
|
25
28
|
|
|
26
29
|
## Interface and preview
|
|
27
30
|
|
|
28
31
|
Use the visible approved MCP surface or the trusted project-local CLI as equal
|
|
29
|
-
peer interfaces. If neither is available, stop.
|
|
30
|
-
|
|
32
|
+
peer interfaces. If neither is available, stop. Interview first, then plan,
|
|
33
|
+
then preview the exact plan for approval.
|
|
34
|
+
|
|
35
|
+
## Interview first
|
|
36
|
+
|
|
37
|
+
Before planning:
|
|
38
|
+
|
|
39
|
+
1. Inventory what you can already read: your own MCP connectors and tools
|
|
40
|
+
(issue trackers such as Jira, YouTrack, Linear, or GitHub Issues; wikis such
|
|
41
|
+
as Confluence or Notion; drives and design tools), and in-repo docs, ADRs,
|
|
42
|
+
and specs.
|
|
43
|
+
2. Ask the human, in one message: what the repository is for; which of those
|
|
44
|
+
sources hold product intent; which are authoritative, supporting, or stale;
|
|
45
|
+
what is missing; and which product areas matter first. If an important
|
|
46
|
+
source has no connector, say which one and suggest connecting it, then
|
|
47
|
+
continue with what is reachable. Never invent access you lack.
|
|
48
|
+
3. Read the confirmed, non-stale sources through your connectors. Harvest one
|
|
49
|
+
normative statement per behavior, each citing its source and an exact
|
|
50
|
+
reference (ticket key, page URL, or section anchor). Keep the source's
|
|
51
|
+
meaning; do not merge, generalize, or resolve conflicts yourself.
|
|
52
|
+
|
|
53
|
+
Declare the result in `bootstrapContext`: `projectSummary`,
|
|
54
|
+
`knowledgeSources` (id, kind, title, locator, authority, optional connector),
|
|
55
|
+
and `intentClaims` (statement, sourceId, reference, optional excerpt). Kibi
|
|
56
|
+
never contacts those sources; it binds what you declare into the plan hash.
|
|
57
|
+
|
|
58
|
+
## Plan and approval
|
|
59
|
+
|
|
60
|
+
Run `kb_plan_bootstrap` (or `plan-bootstrap --input`) read-only with that
|
|
61
|
+
context. Grounded authoritative or supporting claims become cited `req`
|
|
62
|
+
candidates; claims the strict modeler cannot ground come back as authoring
|
|
63
|
+
follow-ups; stale sources produce no candidates; undeclared sources are
|
|
64
|
+
reported in diagnostics. If the plan returns `needs_context`, ask only its
|
|
31
65
|
bounded questions (never more than four), then rerun the planner. Show the
|
|
32
|
-
complete returned `structuredContent.plan`, including its canonical hash
|
|
33
|
-
|
|
34
|
-
`kb_apply_plan`; do not reconstruct
|
|
66
|
+
complete returned `structuredContent.plan`, including its canonical hash and
|
|
67
|
+
which candidates cite which sources, and get explicit approval before any
|
|
68
|
+
write. Pass that plan object unchanged to `kb_apply_plan`; do not reconstruct
|
|
69
|
+
it from preview fields. When a claim contradicts the code or another claim,
|
|
70
|
+
put it to the human instead of choosing.
|
|
35
71
|
|
|
36
72
|
For CLI JSON, use the trusted route with `--input` (for example
|
|
37
73
|
`printf '%s\n' '{}' | kibi status --input -`); MCP and CLI are semantic peers.
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
# Bootstrap resource
|
|
2
2
|
|
|
3
|
-
`kb_plan_bootstrap` is read-only and returns `kibi.bootstrap-plan.v1`.
|
|
3
|
+
`kb_plan_bootstrap` is read-only and returns `kibi.bootstrap-plan.v1`. Declared
|
|
4
|
+
`knowledgeSources` and cited `intentClaims` are part of `declaredContext` and
|
|
5
|
+
therefore of the plan hash; a candidate built from a claim has `sourceKind:
|
|
6
|
+
intent_claim` and evidence rows `intent_claim:<sourceId>:<reference>`,
|
|
7
|
+
`knowledge_source:<kind>:<locator>`, and `source_authority:<authority>`. Its
|
|
8
|
+
requirement keeps the citation as `text_ref: <sourceId>:<reference>`. Review
|
|
4
9
|
candidate evidence, exact actions, dependencies, expected snapshots, source
|
|
5
10
|
hashes, bounded questions, diagnostics, and the canonical `planHash` before
|
|
6
11
|
approving. A preview does not authorize source edits. After approval, pass the
|
|
@@ -56,6 +56,20 @@ printf '%s\n' '{"query":"checkout","limit":10}' | npx --no-install kibi search -
|
|
|
56
56
|
Read `resources/operation-access.md` for the route, result version, effects,
|
|
57
57
|
mutability, and Prolog requirements of each operation.
|
|
58
58
|
|
|
59
|
+
## Working in a git worktree or another directory
|
|
60
|
+
|
|
61
|
+
Kibi MCP servers start in one project and answer from its knowledge base.
|
|
62
|
+
Every Kibi MCP tool accepts `workspaceRoot`: when your working directory is not
|
|
63
|
+
the project the server started in (a git worktree, a sibling checkout), pass
|
|
64
|
+
your working directory as `workspaceRoot` on every call. Host plugins with
|
|
65
|
+
pre-tool hooks add it for you. The server answers from that workspace when it
|
|
66
|
+
is a worktree of the same repository or lies under the client's MCP roots.
|
|
67
|
+
|
|
68
|
+
If a result carries a `workspace_mismatch` diagnostic, the answer came from a
|
|
69
|
+
different workspace than the one you asked for; its `detail.reason` says why.
|
|
70
|
+
Use the CLI from your working directory instead: `npx --no-install kibi ...`
|
|
71
|
+
runs where you are and needs no `workspaceRoot`.
|
|
72
|
+
|
|
59
73
|
## Safe workflow
|
|
60
74
|
|
|
61
75
|
1. Always discover before you mutate: start with `kb_search`, then exact-filter with `kb_query`. Use
|
|
@@ -41,3 +41,7 @@ printf '%s\n' '{"query":"authentication","limit":10}' | npx --no-install kibi se
|
|
|
41
41
|
`_diagnostic_telemetry` is adapter metadata, not business input. Never copy it
|
|
42
42
|
into entity properties. On `committed_with_repairs`, follow typed required
|
|
43
43
|
`nextActions` and do not retry the original mutation.
|
|
44
|
+
|
|
45
|
+
`workspaceRoot` is an MCP-only routing argument naming the directory a call is
|
|
46
|
+
about (see the kibi-usage skill). The CLI JSON routes do not accept it; they
|
|
47
|
+
always run in the current directory.
|