kibi-cli 2.14.0 → 2.16.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/cli-register-proof.d.ts.map +1 -1
- package/dist/cli-register-proof.js +16 -2
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +5 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +83 -4
- package/dist/commands/prove.js +1 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +5 -2
- package/dist/operations/bootstrap/discovery.d.ts.map +1 -1
- package/dist/operations/bootstrap/discovery.js +6 -1
- package/dist/operations/bootstrap/generate.d.ts.map +1 -1
- package/dist/operations/bootstrap/generate.js +1 -0
- package/dist/operations/bootstrap/guidance-actions.d.ts +2 -1
- package/dist/operations/bootstrap/guidance-actions.d.ts.map +1 -1
- package/dist/operations/bootstrap/guidance-actions.js +10 -1
- package/dist/operations/bootstrap/guidance.d.ts +2 -0
- package/dist/operations/bootstrap/guidance.d.ts.map +1 -1
- package/dist/operations/bootstrap/guidance.js +1 -1
- package/dist/operations/bootstrap/plugin-offers.d.ts +16 -0
- package/dist/operations/bootstrap/plugin-offers.d.ts.map +1 -0
- package/dist/operations/bootstrap/plugin-offers.js +66 -0
- package/dist/operations/bootstrap/presentation.d.ts +2 -0
- package/dist/operations/bootstrap/presentation.d.ts.map +1 -1
- package/dist/operations/bootstrap/presentation.js +2 -0
- package/dist/operations/bootstrap/types.d.ts +2 -0
- package/dist/operations/bootstrap/types.d.ts.map +1 -1
- package/dist/operations/modeling/model-requirement.d.ts +5 -0
- package/dist/operations/modeling/model-requirement.d.ts.map +1 -1
- package/dist/operations/modeling/model-requirement.js +17 -5
- package/dist/operations/modeling/predicate-applicability.d.ts.map +1 -1
- package/dist/operations/modeling/predicate-applicability.js +27 -1
- package/dist/operations/modeling/predicate-applyplan.d.ts.map +1 -1
- package/dist/operations/modeling/predicate-applyplan.js +16 -6
- package/dist/operations/modeling/predicate-binding-hints.d.ts +10 -0
- package/dist/operations/modeling/predicate-binding-hints.d.ts.map +1 -1
- package/dist/operations/modeling/predicate-binding-hints.js +74 -0
- package/dist/operations/modeling/predicate-catalog-5.d.ts +2 -2
- package/dist/operations/modeling/predicate-catalog-5.js +2 -2
- package/dist/operations/modeling/predicate-catalog-6.d.ts +9 -0
- package/dist/operations/modeling/predicate-catalog-6.d.ts.map +1 -0
- package/dist/operations/modeling/predicate-catalog-6.js +106 -0
- package/dist/operations/modeling/predicate-catalog.d.ts.map +1 -1
- package/dist/operations/modeling/predicate-catalog.js +2 -0
- package/dist/operations/modeling/predicate-usage-hints-4.d.ts.map +1 -1
- package/dist/operations/modeling/predicate-usage-hints-4.js +32 -0
- package/dist/operations/modeling/suggest-predicates.d.ts.map +1 -1
- package/dist/operations/modeling/suggest-predicates.js +32 -11
- package/dist/operations/mutation/contradictions.d.ts +8 -0
- package/dist/operations/mutation/contradictions.d.ts.map +1 -1
- package/dist/operations/mutation/contradictions.js +13 -0
- package/dist/operations/mutation/source-authoring.d.ts +13 -0
- package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
- package/dist/operations/mutation/source-authoring.js +70 -2
- package/dist/operations/mutation/upsert.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.js +9 -3
- package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
- package/dist/operations/mutation/validate-upsert.js +30 -4
- package/dist/operations/planning/apply-plan.d.ts.map +1 -1
- package/dist/operations/planning/apply-plan.js +15 -0
- package/dist/operations/semantic-advisor/ingestion-boundary.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/ingestion-boundary.js +20 -1
- package/dist/plugins/approved-source-analyzers.generated.d.ts +5 -5
- package/dist/plugins/approved-source-analyzers.generated.js +5 -5
- package/dist/plugins/check-policies.d.ts +24 -0
- package/dist/plugins/check-policies.d.ts.map +1 -0
- package/dist/plugins/check-policies.js +73 -0
- package/dist/plugins/registry.d.ts.map +1 -1
- package/dist/plugins/registry.js +10 -1
- package/dist/prolog.d.ts.map +1 -1
- package/dist/prolog.js +8 -1
- package/dist/proof/inspect.d.ts +18 -1
- package/dist/proof/inspect.d.ts.map +1 -1
- package/dist/proof/inspect.js +17 -8
- package/dist/proof/integration-plan.d.ts +57 -0
- package/dist/proof/integration-plan.d.ts.map +1 -0
- package/dist/proof/integration-plan.js +331 -0
- package/dist/proof/integrations.js +1 -1
- package/dist/public/operations/catalog.d.ts +2 -2
- package/dist/public/operations/check-executor.d.ts +16 -0
- package/dist/public/operations/check-executor.d.ts.map +1 -1
- package/dist/public/operations/check-executor.js +83 -0
- package/dist/public/operations/check-policy-rules.d.ts +49 -0
- package/dist/public/operations/check-policy-rules.d.ts.map +1 -0
- package/dist/public/operations/check-policy-rules.js +305 -0
- package/dist/public/operations/contracts.d.ts.map +1 -1
- package/dist/public/operations/contracts.js +5 -0
- package/dist/public/operations/discovery-executors.d.ts.map +1 -1
- package/dist/public/operations/discovery-executors.js +13 -3
- package/dist/public/operations/migration-plan.d.ts.map +1 -1
- package/dist/public/operations/migration-plan.js +28 -0
- package/dist/public/operations/source-relationship-parity.d.ts.map +1 -1
- package/dist/public/operations/source-relationship-parity.js +16 -1
- package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
- package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
- package/dist/public/operations/specs/check-rules.generated.js +4 -1
- package/dist/public/operations/specs/check.d.ts +1 -1
- package/dist/public/operations/specs/composite.d.ts +16 -3
- package/dist/public/operations/specs/composite.d.ts.map +1 -1
- package/dist/public/operations/specs/composite.js +79 -2
- package/dist/public/operations/specs/modeling.d.ts +1 -1
- package/dist/public/operations/specs/modeling.js +1 -1
- package/dist/public/operations/specs/reporting.d.ts +9 -0
- package/dist/public/operations/specs/reporting.d.ts.map +1 -1
- package/dist/public/operations/specs/reporting.js +6 -2
- package/dist/public/skills/kibi-bootstrap/SKILL.md +3 -2
- package/dist/public/skills/kibi-usage/SKILL.md +82 -3
- package/dist/public/skills/kibi-usage/resources/proof.md +15 -3
- package/dist/public/skills/kibi-usage/resources/ui-requirements.md +42 -3
- package/dist/report/html-report.d.ts.map +1 -1
- package/dist/report/html-report.js +13 -2
- package/dist/utils/branch-store.d.ts +32 -0
- package/dist/utils/branch-store.d.ts.map +1 -1
- package/dist/utils/branch-store.js +122 -1
- package/dist/utils/rule-registry.generated.d.ts +15 -0
- package/dist/utils/rule-registry.generated.d.ts.map +1 -1
- package/dist/utils/rule-registry.generated.js +18 -0
- package/dist/utils/strict-modeling.d.ts +12 -0
- package/dist/utils/strict-modeling.d.ts.map +1 -1
- package/dist/utils/strict-modeling.js +12 -1
- package/package.json +4 -4
- package/src/public/operations/check-executor.ts +112 -0
- package/src/public/operations/check-policy-rules.ts +462 -0
- package/src/public/operations/contracts.ts +6 -0
- package/src/public/operations/discovery-executors.ts +19 -2
- package/src/public/operations/migration-plan.ts +35 -0
- package/src/public/operations/source-relationship-parity.ts +17 -2
- package/src/public/operations/specs/check-rules.generated.ts +4 -1
- package/src/public/operations/specs/composite.ts +110 -11
- package/src/public/operations/specs/modeling.ts +1 -1
- package/src/public/operations/specs/reporting.ts +13 -2
- package/src/public/skills/kibi-bootstrap/SKILL.md +3 -2
- package/src/public/skills/kibi-usage/SKILL.md +82 -3
- package/src/public/skills/kibi-usage/resources/proof.md +15 -3
- package/src/public/skills/kibi-usage/resources/ui-requirements.md +42 -3
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/** Stale-reason code of a branch store that was never compiled. */
|
|
2
|
+
export declare const BRANCH_STORE_NOT_COMPILED = "branch_store_not_compiled";
|
|
3
|
+
/** The kb_check rule that reports it. */
|
|
4
|
+
export declare const BRANCH_STORE_NOT_COMPILED_RULE = "branch-store-not-compiled";
|
|
1
5
|
export type BranchStoreState = "healthy" | "missing" | "incomplete" | "unreadable";
|
|
2
6
|
export type BranchStoreInspection = Readonly<{
|
|
3
7
|
state: BranchStoreState;
|
|
@@ -18,4 +22,32 @@ export declare function inspectBranchStore(workspaceRoot: string, branch: string
|
|
|
18
22
|
*/
|
|
19
23
|
export declare function storeLockJournalReason(storePath: string): Record<string, unknown> | null;
|
|
20
24
|
export declare function branchStoreReason(inspection: BranchStoreInspection): Record<string, unknown> | null;
|
|
25
|
+
/**
|
|
26
|
+
* The number of authored source files under `.kb/`: entity Markdown in the
|
|
27
|
+
* entity lanes plus relationship shards. Filesystem only, like
|
|
28
|
+
* inspectBranchStore, so a status read never compiles anything.
|
|
29
|
+
*/
|
|
30
|
+
export declare function countAuthoredKbSources(workspaceRoot: string): number;
|
|
31
|
+
export type BranchStoreCompilation = Readonly<{
|
|
32
|
+
/** True once a sync (or any write) has committed into the store. */
|
|
33
|
+
compiled: boolean;
|
|
34
|
+
/** The journal CURRENT pointer (`generation-<id>:<sequence>`), if any. */
|
|
35
|
+
generation: string | null;
|
|
36
|
+
}>;
|
|
37
|
+
/**
|
|
38
|
+
* Whether the branch store holds a compilation. A missing store holds none;
|
|
39
|
+
* a journaled store whose CURRENT sequence is still 0 and whose journal holds
|
|
40
|
+
* no graph data was created (by `kibi branch ensure` or by an engine
|
|
41
|
+
* attaching to a new branch) but nothing was ever committed into it, so it is
|
|
42
|
+
* empty. A legacy kb.rdf store counts as compiled.
|
|
43
|
+
*/
|
|
44
|
+
export declare function branchStoreCompilation(inspection: BranchStoreInspection): BranchStoreCompilation;
|
|
45
|
+
/**
|
|
46
|
+
* The single blocking reason for a branch whose store was never compiled
|
|
47
|
+
* while `.kb/` holds authored sources: Kibi stores are per branch and never
|
|
48
|
+
* copied, so a fresh branch (no post-checkout hook) starts empty. Every
|
|
49
|
+
* check against that store would report each authored relationship as
|
|
50
|
+
* missing; the one fix is `kibi sync`.
|
|
51
|
+
*/
|
|
52
|
+
export declare function uncompiledBranchStoreReason(workspaceRoot: string, inspection: BranchStoreInspection, branch: string): Record<string, unknown> | null;
|
|
21
53
|
//# sourceMappingURL=branch-store.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"branch-store.d.ts","sourceRoot":"","sources":["../../src/utils/branch-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"branch-store.d.ts","sourceRoot":"","sources":["../../src/utils/branch-store.ts"],"names":[],"mappings":"AAwBA,mEAAmE;AACnE,eAAO,MAAM,yBAAyB,8BAA8B,CAAC;AACrE,yCAAyC;AACzC,eAAO,MAAM,8BAA8B,8BAA8B,CAAC;AAE1E,MAAM,MAAM,gBAAgB,GACxB,SAAS,GACT,SAAS,GACT,YAAY,GACZ,YAAY,CAAC;AAEjB,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,KAAK,EAAE,gBAAgB,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,OAAO,CAAC;CAC3B,CAAC,CAAC;AAEH;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,GACb,qBAAqB,CA0GvB;AAED;;;;GAIG;AAEH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,MAAM,GAChB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAiBhC;AAED,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,qBAAqB,GAChC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAWhC;AA6BD;;;;GAIG;AAEH,wBAAgB,sBAAsB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAOpE;AAED,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAC5C,oEAAoE;IACpE,QAAQ,EAAE,OAAO,CAAC;IAClB,0EAA0E;IAC1E,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC,CAAC;AAEH;;;;;;GAMG;AAEH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,qBAAqB,GAChC,sBAAsB,CAwBxB;AAkBD;;;;;;GAMG;AAEH,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,qBAAqB,EACjC,MAAM,EAAE,MAAM,GACb,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAwBhC"}
|
|
@@ -2,10 +2,15 @@
|
|
|
2
2
|
Kibi — repo-local, per-branch, queryable long-term memory for software projects
|
|
3
3
|
Copyright (C) 2026 Piotr Franczyk
|
|
4
4
|
*/
|
|
5
|
-
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
5
|
+
import { existsSync, readFileSync, readdirSync, statSync, } from "node:fs";
|
|
6
6
|
import * as path from "node:path";
|
|
7
7
|
import { classifyStoreLockHolder, readStoreLockOwner, } from "../prolog/store-lock.js";
|
|
8
8
|
import { branchStoreManifestMatches, branchStorePath, legacyBranchStorePath, } from "./branch-store-locator.js";
|
|
9
|
+
import { ENTITY_LANES, KB_ROOT } from "./kb-paths.js";
|
|
10
|
+
/** Stale-reason code of a branch store that was never compiled. */
|
|
11
|
+
export const BRANCH_STORE_NOT_COMPILED = "branch_store_not_compiled";
|
|
12
|
+
/** The kb_check rule that reports it. */
|
|
13
|
+
export const BRANCH_STORE_NOT_COMPILED_RULE = "branch-store-not-compiled";
|
|
9
14
|
/**
|
|
10
15
|
* Performs only filesystem checks. It deliberately never starts the engine or
|
|
11
16
|
* attaches Prolog, so callers can still explain a broken branch store.
|
|
@@ -155,3 +160,119 @@ export function branchStoreReason(inspection) {
|
|
|
155
160
|
: { command_argv: ["kibi", "branch", "ensure"], applyRequired: false },
|
|
156
161
|
};
|
|
157
162
|
}
|
|
163
|
+
/** Directories under .kb/ that hold authored, Git-tracked entity sources. */
|
|
164
|
+
const AUTHORED_SOURCE_DIRECTORIES = [
|
|
165
|
+
...ENTITY_LANES.map((lane) => [lane, ".md"]),
|
|
166
|
+
["adrs", ".md"],
|
|
167
|
+
["relationships", ".yaml"],
|
|
168
|
+
];
|
|
169
|
+
function countFiles(directory, extension) {
|
|
170
|
+
let count = 0;
|
|
171
|
+
let entries;
|
|
172
|
+
try {
|
|
173
|
+
entries = readdirSync(directory, { withFileTypes: true });
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
return 0;
|
|
177
|
+
}
|
|
178
|
+
for (const entry of entries) {
|
|
179
|
+
if (entry.isDirectory()) {
|
|
180
|
+
count += countFiles(path.join(directory, entry.name), extension);
|
|
181
|
+
}
|
|
182
|
+
else if (entry.isFile() && entry.name.endsWith(extension)) {
|
|
183
|
+
count += 1;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return count;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* The number of authored source files under `.kb/`: entity Markdown in the
|
|
190
|
+
* entity lanes plus relationship shards. Filesystem only, like
|
|
191
|
+
* inspectBranchStore, so a status read never compiles anything.
|
|
192
|
+
*/
|
|
193
|
+
// implements REQ-cli-status-pre-first-sync
|
|
194
|
+
export function countAuthoredKbSources(workspaceRoot) {
|
|
195
|
+
const kbRoot = path.join(workspaceRoot, KB_ROOT);
|
|
196
|
+
return AUTHORED_SOURCE_DIRECTORIES.reduce((total, [directory, extension]) => total + countFiles(path.join(kbRoot, directory), extension), 0);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Whether the branch store holds a compilation. A missing store holds none;
|
|
200
|
+
* a journaled store whose CURRENT sequence is still 0 and whose journal holds
|
|
201
|
+
* no graph data was created (by `kibi branch ensure` or by an engine
|
|
202
|
+
* attaching to a new branch) but nothing was ever committed into it, so it is
|
|
203
|
+
* empty. A legacy kb.rdf store counts as compiled.
|
|
204
|
+
*/
|
|
205
|
+
// implements REQ-cli-status-pre-first-sync
|
|
206
|
+
export function branchStoreCompilation(inspection) {
|
|
207
|
+
if (inspection.state === "missing") {
|
|
208
|
+
return { compiled: false, generation: null };
|
|
209
|
+
}
|
|
210
|
+
const currentPath = path.join(inspection.path, "CURRENT");
|
|
211
|
+
let current = "";
|
|
212
|
+
try {
|
|
213
|
+
current = existsSync(currentPath)
|
|
214
|
+
? readFileSync(currentPath, "utf8").trim()
|
|
215
|
+
: "";
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
current = "";
|
|
219
|
+
}
|
|
220
|
+
if (current === "") {
|
|
221
|
+
// A healthy store without CURRENT is a legacy kb.rdf store.
|
|
222
|
+
return { compiled: inspection.state === "healthy", generation: null };
|
|
223
|
+
}
|
|
224
|
+
const sequence = Number(current.split(":").at(-1));
|
|
225
|
+
return {
|
|
226
|
+
compiled: (Number.isFinite(sequence) && sequence > 0) ||
|
|
227
|
+
journalHoldsGraphData(inspection.path),
|
|
228
|
+
generation: current,
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Whether the journal directory holds persisted graph data. An empty store
|
|
233
|
+
* has only `rdf/lock`; a store migrated from a legacy kb.rdf holds the
|
|
234
|
+
* imported graph under a fresh `generation-…:0` pointer, so it is compiled
|
|
235
|
+
* although its sequence is still 0.
|
|
236
|
+
*/
|
|
237
|
+
function journalHoldsGraphData(storePath) {
|
|
238
|
+
try {
|
|
239
|
+
return readdirSync(path.join(storePath, "rdf")).some((entry) => entry !== "lock" && !entry.startsWith("."));
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* The single blocking reason for a branch whose store was never compiled
|
|
247
|
+
* while `.kb/` holds authored sources: Kibi stores are per branch and never
|
|
248
|
+
* copied, so a fresh branch (no post-checkout hook) starts empty. Every
|
|
249
|
+
* check against that store would report each authored relationship as
|
|
250
|
+
* missing; the one fix is `kibi sync`.
|
|
251
|
+
*/
|
|
252
|
+
// implements REQ-cli-status-pre-first-sync
|
|
253
|
+
export function uncompiledBranchStoreReason(workspaceRoot, inspection, branch) {
|
|
254
|
+
if (inspection.state !== "healthy" && inspection.state !== "missing") {
|
|
255
|
+
return null;
|
|
256
|
+
}
|
|
257
|
+
const compilation = branchStoreCompilation(inspection);
|
|
258
|
+
if (compilation.compiled)
|
|
259
|
+
return null;
|
|
260
|
+
const authoredSources = countAuthoredKbSources(workspaceRoot);
|
|
261
|
+
if (authoredSources === 0)
|
|
262
|
+
return null;
|
|
263
|
+
const storeState = inspection.state === "missing"
|
|
264
|
+
? "does not exist yet"
|
|
265
|
+
: `is empty (${compilation.generation ?? "no generation"}: nothing compiled)`;
|
|
266
|
+
return {
|
|
267
|
+
code: BRANCH_STORE_NOT_COMPILED,
|
|
268
|
+
path: inspection.path,
|
|
269
|
+
entityIds: [],
|
|
270
|
+
detail: `The KB store for branch ${branch} ${storeState}, while .kb/ holds ${authoredSources} authored source file(s). Kibi compiles one store per branch and never copies another branch's, so every query and check reads an empty KB until this branch is compiled.`,
|
|
271
|
+
remediation: { command_argv: ["kibi", "sync"], applyRequired: false },
|
|
272
|
+
blocking: true,
|
|
273
|
+
authoredSources,
|
|
274
|
+
...(compilation.generation !== null
|
|
275
|
+
? { generation: compilation.generation }
|
|
276
|
+
: {}),
|
|
277
|
+
};
|
|
278
|
+
}
|
|
@@ -23,6 +23,11 @@ export declare const GENERATED_RULES: readonly [{
|
|
|
23
23
|
readonly description: "Authored Markdown and relationship-shard edges must exactly match the compiled KB";
|
|
24
24
|
readonly enforcementClass: "canonical";
|
|
25
25
|
readonly category: "integrity";
|
|
26
|
+
}, {
|
|
27
|
+
readonly name: "branch-store-not-compiled";
|
|
28
|
+
readonly description: "The current branch's KB store must be compiled from the authored .kb/ sources; a missing or empty store is reported once, naming kibi sync, instead of every store-backed rule reading an empty KB";
|
|
29
|
+
readonly enforcementClass: "canonical";
|
|
30
|
+
readonly category: "integrity";
|
|
26
31
|
}, {
|
|
27
32
|
readonly name: "source-path-dangling";
|
|
28
33
|
readonly description: "An authored entity's source field must name an existing workspace path (a #anchor suffix is ignored), an existing entity id, or an http(s) URL; a missing source is allowed";
|
|
@@ -223,5 +228,15 @@ export declare const GENERATED_RULES: readonly [{
|
|
|
223
228
|
readonly enforcementClass: "advisory";
|
|
224
229
|
readonly category: "lifecycle";
|
|
225
230
|
readonly diagnosticSeverity: "info";
|
|
231
|
+
}, {
|
|
232
|
+
readonly name: "policy-ownership";
|
|
233
|
+
readonly description: "When a plugin activated for kibi.check-policy.v1 declares ownership rules, every production symbol in a rule's file set must implement a current requirement grounded (requires_predicate) in one of the rule's predicates; projects without an activated check policy are unaffected";
|
|
234
|
+
readonly enforcementClass: "canonical";
|
|
235
|
+
readonly category: "traceability";
|
|
236
|
+
}, {
|
|
237
|
+
readonly name: "policy-markers";
|
|
238
|
+
readonly description: "When a plugin activated for kibi.check-policy.v1 declares marker rules, every file implementing a requirement grounded in the rule's pattern predicate (with its declared sibling files) must contain each marker the KB declares for that pattern";
|
|
239
|
+
readonly enforcementClass: "canonical";
|
|
240
|
+
readonly category: "traceability";
|
|
226
241
|
}];
|
|
227
242
|
//# sourceMappingURL=rule-registry.generated.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule-registry.generated.d.ts","sourceRoot":"","sources":["../../src/utils/rule-registry.generated.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,eAAe
|
|
1
|
+
{"version":3,"file":"rule-registry.generated.d.ts","sourceRoot":"","sources":["../../src/utils/rule-registry.generated.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4UlB,CAAC"}
|
|
@@ -38,6 +38,12 @@ export const GENERATED_RULES = [
|
|
|
38
38
|
enforcementClass: "canonical",
|
|
39
39
|
category: "integrity",
|
|
40
40
|
},
|
|
41
|
+
{
|
|
42
|
+
name: "branch-store-not-compiled",
|
|
43
|
+
description: "The current branch's KB store must be compiled from the authored .kb/ sources; a missing or empty store is reported once, naming kibi sync, instead of every store-backed rule reading an empty KB",
|
|
44
|
+
enforcementClass: "canonical",
|
|
45
|
+
category: "integrity",
|
|
46
|
+
},
|
|
41
47
|
{
|
|
42
48
|
name: "source-path-dangling",
|
|
43
49
|
description: "An authored entity's source field must name an existing workspace path (a #anchor suffix is ignored), an existing entity id, or an http(s) URL; a missing source is allowed",
|
|
@@ -277,4 +283,16 @@ export const GENERATED_RULES = [
|
|
|
277
283
|
category: "lifecycle",
|
|
278
284
|
diagnosticSeverity: "info",
|
|
279
285
|
},
|
|
286
|
+
{
|
|
287
|
+
name: "policy-ownership",
|
|
288
|
+
description: "When a plugin activated for kibi.check-policy.v1 declares ownership rules, every production symbol in a rule's file set must implement a current requirement grounded (requires_predicate) in one of the rule's predicates; projects without an activated check policy are unaffected",
|
|
289
|
+
enforcementClass: "canonical",
|
|
290
|
+
category: "traceability",
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
name: "policy-markers",
|
|
294
|
+
description: "When a plugin activated for kibi.check-policy.v1 declares marker rules, every file implementing a requirement grounded in the rule's pattern predicate (with its declared sibling files) must contain each marker the KB declares for that pattern",
|
|
295
|
+
enforcementClass: "canonical",
|
|
296
|
+
category: "traceability",
|
|
297
|
+
},
|
|
280
298
|
];
|
|
@@ -12,6 +12,12 @@ export interface SemanticClaim {
|
|
|
12
12
|
export interface StrictModelInput {
|
|
13
13
|
claim: SemanticClaim;
|
|
14
14
|
statement: string;
|
|
15
|
+
/**
|
|
16
|
+
* The requirement the write set updates. When set it replaces the minted
|
|
17
|
+
* REQ-AUTO-<hash> id; fact ids, subject_key and the claim stay derived from
|
|
18
|
+
* the claim.
|
|
19
|
+
*/
|
|
20
|
+
requirementId?: string;
|
|
15
21
|
}
|
|
16
22
|
type EntityProperties = Partial<Omit<BaseEntity, "created_at" | "updated_at"> & FactFields> & {
|
|
17
23
|
id: string;
|
|
@@ -65,5 +71,11 @@ export declare function buildStrictWriteSet(input: StrictModelInput): StrictWrit
|
|
|
65
71
|
export declare function modelRequirementClaims(inputs: ReadonlyArray<StrictModelInput>): StrictWriteSet[];
|
|
66
72
|
export declare function normalizeSourceKey(value: string): string;
|
|
67
73
|
export declare function normalizeTextRef(provenance: string | undefined, source: string): string;
|
|
74
|
+
/**
|
|
75
|
+
* The file an authored fact lives in: `.kb/facts/<id>.md`. Kibi writes every
|
|
76
|
+
* fact there (the filename stem equals the id), so a plan that points at an
|
|
77
|
+
* existing fact names this path.
|
|
78
|
+
*/
|
|
79
|
+
export declare function factSourcePath(factId: string): string;
|
|
68
80
|
export {};
|
|
69
81
|
//# sourceMappingURL=strict-modeling.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strict-modeling.d.ts","sourceRoot":"","sources":["../../src/utils/strict-modeling.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAKlE,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,IAAI,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,UAAU,CAAC;IAC3E,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"strict-modeling.d.ts","sourceRoot":"","sources":["../../src/utils/strict-modeling.ts"],"names":[],"mappings":"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"}
|
|
@@ -83,7 +83,9 @@ export function buildStableRequirementIds(claim) {
|
|
|
83
83
|
export function buildStrictWriteSet(input) {
|
|
84
84
|
const statement = normalizeStatement(input.statement);
|
|
85
85
|
const confidence = normalizeConfidence(input.claim.confidence);
|
|
86
|
-
const
|
|
86
|
+
const minted = buildStableRequirementIds(input.claim);
|
|
87
|
+
const requirementId = input.requirementId?.trim();
|
|
88
|
+
const ids = requirementId ? { ...minted, reqId: requirementId } : minted;
|
|
87
89
|
const textRef = normalizeTextRef(input.claim.provenance, input.claim.source);
|
|
88
90
|
const metadataTags = buildMetadataTags({
|
|
89
91
|
confidence,
|
|
@@ -409,3 +411,12 @@ function normalizeEntityDirectory(directory) {
|
|
|
409
411
|
function buildEntitySourcePath(directory, entityId) {
|
|
410
412
|
return `${directory}/${entityId}.md`;
|
|
411
413
|
}
|
|
414
|
+
/**
|
|
415
|
+
* The file an authored fact lives in: `.kb/facts/<id>.md`. Kibi writes every
|
|
416
|
+
* fact there (the filename stem equals the id), so a plan that points at an
|
|
417
|
+
* existing fact names this path.
|
|
418
|
+
*/
|
|
419
|
+
// implements REQ-kibi-subject-vocabulary
|
|
420
|
+
export function factSourcePath(factId) {
|
|
421
|
+
return buildEntitySourcePath(resolveEntitySourcePaths().facts, factId);
|
|
422
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kibi-cli",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.16.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Kibi CLI for knowledge base management",
|
|
6
6
|
"engines": {
|
|
@@ -235,9 +235,9 @@
|
|
|
235
235
|
"fast-glob": "^3.2.12",
|
|
236
236
|
"gray-matter": "^4.0.3",
|
|
237
237
|
"js-yaml": "^4.1.0",
|
|
238
|
-
"kibi-core": "^0.
|
|
239
|
-
"kibi-plugin-builtin": "^0.
|
|
240
|
-
"kibi-plugin-sdk": "^0.
|
|
238
|
+
"kibi-core": "^0.18.1",
|
|
239
|
+
"kibi-plugin-builtin": "^0.5.0",
|
|
240
|
+
"kibi-plugin-sdk": "^0.5.0",
|
|
241
241
|
"kibi-swipl": "^1.0.1",
|
|
242
242
|
"saxes": "^6.0.0",
|
|
243
243
|
"ignore": "^5.3.0",
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { runAggregatedChecks } from "../../commands/aggregated-checks.js";
|
|
2
|
+
import { resolveBranchAttachment } from "../../utils/branch-resolver.js";
|
|
3
|
+
import {
|
|
4
|
+
BRANCH_STORE_NOT_COMPILED_RULE,
|
|
5
|
+
inspectBranchStore,
|
|
6
|
+
uncompiledBranchStoreReason,
|
|
7
|
+
} from "../../utils/branch-store.js";
|
|
2
8
|
/*
|
|
3
9
|
Kibi — repo-local, per-branch, queryable long-term memory for software projects
|
|
4
10
|
Copyright (C) 2026 Piotr Franczyk
|
|
@@ -33,6 +39,7 @@ import {
|
|
|
33
39
|
resolveCheckRules,
|
|
34
40
|
stagedEntityIdStyleDiagnostics,
|
|
35
41
|
} from "./check-helpers.js";
|
|
42
|
+
import { collectCheckPolicyViolations } from "./check-policy-rules.js";
|
|
36
43
|
import { executeStatus } from "./discovery-executors.js";
|
|
37
44
|
import { collectEntityContextViolations } from "./entity-context.js";
|
|
38
45
|
import {
|
|
@@ -73,6 +80,14 @@ export {
|
|
|
73
80
|
|
|
74
81
|
export type CheckExecutionOptions = {
|
|
75
82
|
readonly collectFullQualityDiagnosticsForExplicitRules?: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* The engine reads the current branch's store although the context carries
|
|
85
|
+
* no branch attachment (the `kibi check` engine path). A context with a
|
|
86
|
+
* branch attachment (the CLI and MCP runtimes) implies it; without either,
|
|
87
|
+
* the attached store is unknown (an explicit --kb-path store or an injected
|
|
88
|
+
* test store) and the branch-store compilation check is skipped.
|
|
89
|
+
*/
|
|
90
|
+
readonly branchStoreAttached?: boolean;
|
|
76
91
|
};
|
|
77
92
|
|
|
78
93
|
function requireProlog(context: OperationContext): PrologPort {
|
|
@@ -125,6 +140,50 @@ async function readStatusMigrationPlan(
|
|
|
125
140
|
}
|
|
126
141
|
}
|
|
127
142
|
|
|
143
|
+
/**
|
|
144
|
+
* The one finding for a branch whose store was never compiled while .kb/
|
|
145
|
+
* holds authored sources. Every store-backed rule would read an empty KB
|
|
146
|
+
* (source-relationship-parity alone reports each authored relationship as
|
|
147
|
+
* missing), so kb_check reports this instead of any of them.
|
|
148
|
+
*/
|
|
149
|
+
// implements REQ-cli-status-pre-first-sync
|
|
150
|
+
export function uncompiledBranchStoreViolation(
|
|
151
|
+
context: OperationContext,
|
|
152
|
+
workspaceRoot: string,
|
|
153
|
+
): Violation | null {
|
|
154
|
+
let attachment: ReturnType<typeof resolveBranchAttachment>;
|
|
155
|
+
try {
|
|
156
|
+
attachment =
|
|
157
|
+
context.branchAttachment ?? resolveBranchAttachment(workspaceRoot);
|
|
158
|
+
} catch {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
if ("error" in attachment) return null;
|
|
162
|
+
const store = inspectBranchStore(workspaceRoot, attachment.kbBranch);
|
|
163
|
+
const reason = uncompiledBranchStoreReason(
|
|
164
|
+
workspaceRoot,
|
|
165
|
+
store,
|
|
166
|
+
attachment.kbBranch,
|
|
167
|
+
);
|
|
168
|
+
if (reason === null) return null;
|
|
169
|
+
return {
|
|
170
|
+
rule: BRANCH_STORE_NOT_COMPILED_RULE,
|
|
171
|
+
entityId: attachment.kbBranch,
|
|
172
|
+
description: String(reason.detail),
|
|
173
|
+
suggestion:
|
|
174
|
+
"Run kibi sync to compile this branch's store from the authored .kb/ sources (or apply the branch-store-compile action of the returned migrationPlan with kb_apply_plan), then rerun kb_check. Run kibi init once to install the git hooks that compile a new branch on checkout.",
|
|
175
|
+
source: store.path,
|
|
176
|
+
evidence: {
|
|
177
|
+
store: { state: store.state, path: store.path },
|
|
178
|
+
authoredSources: reason.authoredSources,
|
|
179
|
+
...(reason.generation !== undefined
|
|
180
|
+
? { generation: reason.generation }
|
|
181
|
+
: {}),
|
|
182
|
+
remediation: reason.remediation,
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
128
187
|
// implements REQ-kibi-operation-interface-parity, REQ-002
|
|
129
188
|
export async function executeCheck(
|
|
130
189
|
args: CheckInput,
|
|
@@ -153,6 +212,53 @@ export async function executeCheck(
|
|
|
153
212
|
? { maxDiagnostics: args.maxDiagnostics }
|
|
154
213
|
: {};
|
|
155
214
|
|
|
215
|
+
const uncompiled =
|
|
216
|
+
context.branchAttachment !== undefined ||
|
|
217
|
+
options.branchStoreAttached === true
|
|
218
|
+
? uncompiledBranchStoreViolation(context, workspaceRoot)
|
|
219
|
+
: null;
|
|
220
|
+
if (uncompiled !== null) {
|
|
221
|
+
const violations = [uncompiled];
|
|
222
|
+
const statusPlan = await readStatusMigrationPlan(context);
|
|
223
|
+
const migrationPlan = await migrationPlanForCheck(
|
|
224
|
+
context,
|
|
225
|
+
violations,
|
|
226
|
+
[],
|
|
227
|
+
statusPlan,
|
|
228
|
+
);
|
|
229
|
+
return {
|
|
230
|
+
content: [
|
|
231
|
+
{
|
|
232
|
+
type: "text",
|
|
233
|
+
text: buildSummary({
|
|
234
|
+
violations,
|
|
235
|
+
impactResult,
|
|
236
|
+
qualityDiagnostics: [],
|
|
237
|
+
}),
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
structuredContent: buildStructuredContent({
|
|
241
|
+
violations,
|
|
242
|
+
diagnostics: [
|
|
243
|
+
{
|
|
244
|
+
category: "SYNC_ERROR",
|
|
245
|
+
severity: "error",
|
|
246
|
+
message: uncompiled.description,
|
|
247
|
+
...(uncompiled.source !== undefined
|
|
248
|
+
? { file: uncompiled.source }
|
|
249
|
+
: {}),
|
|
250
|
+
...(uncompiled.suggestion !== undefined
|
|
251
|
+
? { suggestion: uncompiled.suggestion }
|
|
252
|
+
: {}),
|
|
253
|
+
},
|
|
254
|
+
],
|
|
255
|
+
qualityDiagnostics: [],
|
|
256
|
+
impactResult,
|
|
257
|
+
migrationPlan,
|
|
258
|
+
}),
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
|
|
156
262
|
if (rulesAllowlist.size === 0) {
|
|
157
263
|
const qualityDiagnostics =
|
|
158
264
|
hasExplicitRules &&
|
|
@@ -229,6 +335,11 @@ export async function executeCheck(
|
|
|
229
335
|
rulesAllowlist,
|
|
230
336
|
workspaceRoot,
|
|
231
337
|
);
|
|
338
|
+
const checkPolicyFindings = await collectCheckPolicyViolations(
|
|
339
|
+
prolog,
|
|
340
|
+
rulesAllowlist,
|
|
341
|
+
workspaceRoot,
|
|
342
|
+
);
|
|
232
343
|
const partitioned = partitionCheckFindings([
|
|
233
344
|
...aggregatedFindings,
|
|
234
345
|
...queryPlanViolations,
|
|
@@ -237,6 +348,7 @@ export async function executeCheck(
|
|
|
237
348
|
...predicateConformanceFindings,
|
|
238
349
|
...originReviewFindings,
|
|
239
350
|
...entityContextFindings,
|
|
351
|
+
...checkPolicyFindings,
|
|
240
352
|
]);
|
|
241
353
|
const violations: Violation[] = partitioned.violations;
|
|
242
354
|
|