kibi-cli 2.20.0 → 2.21.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/commands/migrate.d.ts +2 -0
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +32 -6
- package/dist/commands/sync/discovery.d.ts.map +1 -1
- package/dist/commands/sync/discovery.js +14 -2
- package/dist/extractors/markdown.d.ts.map +1 -1
- package/dist/extractors/markdown.js +2 -1
- package/dist/operations/migration/kb-sources.d.ts +5 -1
- package/dist/operations/migration/kb-sources.d.ts.map +1 -1
- package/dist/operations/migration/kb-sources.js +28 -1
- package/dist/operations/mutation/source-authoring.d.ts +8 -0
- package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
- package/dist/operations/mutation/source-authoring.js +33 -0
- package/dist/operations/mutation/validation.d.ts.map +1 -1
- package/dist/operations/mutation/validation.js +2 -1
- package/dist/operations/semantic-advisor/clauses.d.ts +9 -0
- package/dist/operations/semantic-advisor/clauses.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/clauses.js +24 -0
- package/dist/public/operations/catalog.d.ts +2 -2
- package/dist/public/operations/migration-plan.d.ts.map +1 -1
- package/dist/public/operations/migration-plan.js +37 -7
- package/dist/public/operations/specs/mutation-schemas.d.ts +2 -2
- package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
- package/dist/public/operations/specs/mutation-schemas.js +8 -17
- package/dist/public/operations/specs/upsert.d.ts +2 -2
- package/dist/public/schemas/entity.d.ts.map +1 -1
- package/dist/public/schemas/entity.js +2 -13
- package/dist/public/skills/kibi-usage/SKILL.md +3 -1
- package/dist/public/skills/kibi-usage/resources/fact-lanes.md +1 -1
- package/dist/public/skills/kibi-usage/resources/ui-requirements.md +2 -2
- package/dist/public/skills/kibi-usage/resources/workflows.md +1 -1
- package/dist/schemas/entity.schema.json +2 -25
- package/package.json +1 -1
- package/src/public/operations/migration-plan.ts +41 -9
- package/src/public/operations/specs/mutation-schemas.ts +8 -17
- package/src/public/schemas/entity.ts +2 -13
- package/src/public/skills/kibi-usage/SKILL.md +3 -1
- package/src/public/skills/kibi-usage/resources/fact-lanes.md +1 -1
- package/src/public/skills/kibi-usage/resources/ui-requirements.md +2 -2
- package/src/public/skills/kibi-usage/resources/workflows.md +1 -1
- package/src/schemas/entity.schema.json +2 -25
|
@@ -5,6 +5,8 @@ interface MigrateOptions {
|
|
|
5
5
|
applySafe?: boolean;
|
|
6
6
|
approvedPlanHash?: string;
|
|
7
7
|
approvedActionIds?: string[];
|
|
8
|
+
/** `--approved-action <id>` as the CLI parser spells it; same as approvedActionIds. */
|
|
9
|
+
approvedAction?: string[];
|
|
8
10
|
workspaceRoot?: string;
|
|
9
11
|
/** Internal migration-plan executor: create only the canonical baseline manifest. */
|
|
10
12
|
initializeMissingConfig?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AAiEA,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qFAAqF;IACrF,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AAuKD,wBAAgB,mBAAmB,CACjC,gBAAgB,EAAE,OAAO,EACzB,UAAU,EAAE,MAAM,GAAG,IAAI,GACxB,MAAM,CAUR;AAsXD,wBAAgB,+BAA+B,IAAI;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAKtE;AAGD,wBAAsB,cAAc,CAClC,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAiW/B"}
|
|
1
|
+
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AAiEA,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,uFAAuF;IACvF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qFAAqF;IACrF,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AAuKD,wBAAgB,mBAAmB,CACjC,gBAAgB,EAAE,OAAO,EACzB,UAAU,EAAE,MAAM,GAAG,IAAI,GACxB,MAAM,CAUR;AAsXD,wBAAgB,+BAA+B,IAAI;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAKtE;AAGD,wBAAsB,cAAc,CAClC,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAiW/B"}
|
package/dist/commands/migrate.js
CHANGED
|
@@ -761,20 +761,47 @@ async function buildWorkspaceMigrationPlan(workspaceRoot = process.cwd()) {
|
|
|
761
761
|
}
|
|
762
762
|
return mergeMigrationPlans(plans);
|
|
763
763
|
}
|
|
764
|
+
/**
|
|
765
|
+
* The action ids approved on the command line. The CLI parser stores
|
|
766
|
+
* `--approved-action` as `approvedAction`; in-process callers pass
|
|
767
|
+
* `approvedActionIds`. Either spelling limits `--apply-safe` to those ids.
|
|
768
|
+
*/
|
|
769
|
+
// implements REQ-cli-schema-migration
|
|
770
|
+
function approvedActionIdsOf(options) {
|
|
771
|
+
const ids = [
|
|
772
|
+
...(options.approvedActionIds ?? []),
|
|
773
|
+
...(options.approvedAction ?? []),
|
|
774
|
+
]
|
|
775
|
+
.map((id) => id.trim())
|
|
776
|
+
.filter((id) => id.length > 0);
|
|
777
|
+
return [...new Set(ids)];
|
|
778
|
+
}
|
|
764
779
|
async function migratePlanCommand(options) {
|
|
765
780
|
const workspaceRoot = path.resolve(options.workspaceRoot ?? process.cwd());
|
|
766
781
|
const plan = await buildWorkspaceMigrationPlan(workspaceRoot);
|
|
767
|
-
|
|
768
|
-
|
|
782
|
+
// `--yes` with JSON output applies every ready automatic action of the plan
|
|
783
|
+
// it would otherwise only print; `--dry-run` still only prints it.
|
|
784
|
+
const approveWholePlan = options.applySafe !== true &&
|
|
785
|
+
options.yes === true &&
|
|
786
|
+
options.dryRun !== true &&
|
|
787
|
+
options.format === "json";
|
|
788
|
+
if (options.applySafe === true || approveWholePlan) {
|
|
789
|
+
const approvedPlanHash = approveWholePlan
|
|
790
|
+
? plan.planHash
|
|
791
|
+
: options.approvedPlanHash;
|
|
792
|
+
if (!approvedPlanHash) {
|
|
769
793
|
console.error("--apply-safe requires --approved-plan-hash <sha256>.");
|
|
770
794
|
return { exitCode: 2 };
|
|
771
795
|
}
|
|
772
|
-
if (
|
|
796
|
+
if (approvedPlanHash !== plan.planHash) {
|
|
773
797
|
console.error("Migration plan changed; regenerate the plan and approve its current hash.");
|
|
774
798
|
return { exitCode: 2 };
|
|
775
799
|
}
|
|
776
|
-
const
|
|
777
|
-
?
|
|
800
|
+
const explicitActionIds = approveWholePlan
|
|
801
|
+
? []
|
|
802
|
+
: approvedActionIdsOf(options);
|
|
803
|
+
const approvedActionIds = explicitActionIds.length > 0
|
|
804
|
+
? explicitActionIds
|
|
778
805
|
: plan.actions
|
|
779
806
|
.filter((action) => action.state === "ready" && action.autoApplicable)
|
|
780
807
|
.map((action) => action.id);
|
|
@@ -788,7 +815,6 @@ async function migratePlanCommand(options) {
|
|
|
788
815
|
import("../public/operations/specs/planning.js"),
|
|
789
816
|
import("../cli-json-command.js"),
|
|
790
817
|
]);
|
|
791
|
-
const approvedPlanHash = options.approvedPlanHash;
|
|
792
818
|
const execute = () => executeOperation(createCliRuntime({ workspaceRoot }), applyPlanSpec, {
|
|
793
819
|
plan,
|
|
794
820
|
approvedPlanHash,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/discovery.ts"],"names":[],"mappings":"AAkCA,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,+EAA+E;IAC/E,6BAA6B,CAAC,EAAE,OAAO,CAAC;CACzC,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/discovery.ts"],"names":[],"mappings":"AAkCA,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4BAA4B,CAAC,EAAE,OAAO,CAAC;IACvC,+EAA+E;IAC/E,6BAA6B,CAAC,EAAE,OAAO,CAAC;CACzC,CAAC,CAAC;AAEH;;;;;;;GAOG;AACH,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAwGH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAOlD;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAShE;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAUxD;AAED,wBAAgB,mCAAmC,CACjD,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,SAAS,4BAA4B,EAAE,GAChD,IAAI,CA6CN;AAsBD,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,GAAG,SAAS,GAC1B,MAAM,GAAG,IAAI,CAIf;AAED,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC;IACT,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gBAAgB,EAAE,MAAM,CAAC;IACzB,4BAA4B,EAAE,4BAA4B,EAAE,CAAC;CAC9D,CAAC,CAgGD"}
|
|
@@ -34,7 +34,14 @@ async function gitTrackedPaths(cwd) {
|
|
|
34
34
|
.filter(Boolean)
|
|
35
35
|
.map((value) => value.replaceAll("\\", "/")));
|
|
36
36
|
}
|
|
37
|
-
|
|
37
|
+
/**
|
|
38
|
+
* The sources bound by pending receipts. A receipt whose file Git now tracks
|
|
39
|
+
* is kept as an input but not compared, whatever its hash says: the tracked
|
|
40
|
+
* bytes are the authored input, and the caller retires that receipt. Only a
|
|
41
|
+
* receipt for a still-untracked file can refuse the sync on hash drift.
|
|
42
|
+
*/
|
|
43
|
+
// implements REQ-core-atomic-upsert-persistence
|
|
44
|
+
function pendingSourcePaths(cwd, recoverMissing, tracked = new Set()) {
|
|
38
45
|
const root = path.join(cwd, ".kb", "recovery", "pending-sources");
|
|
39
46
|
if (!existsSync(root)) {
|
|
40
47
|
return { paths: new Map(), recoveredReceipts: [] };
|
|
@@ -53,6 +60,11 @@ function pendingSourcePaths(cwd, recoverMissing) {
|
|
|
53
60
|
typeof receipt.afterHash === "string" &&
|
|
54
61
|
/^[a-f0-9]{64}$/i.test(receipt.afterHash)) {
|
|
55
62
|
const relative = receipt.path.replaceAll("\\", "/");
|
|
63
|
+
if (tracked.has(relative)) {
|
|
64
|
+
// Still an authored input; only the stale hash is ignored.
|
|
65
|
+
paths.set(relative, receipt.afterHash);
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
56
68
|
const absolute = path.resolve(cwd, relative);
|
|
57
69
|
if (!absolute.startsWith(`${path.resolve(cwd)}${path.sep}`)) {
|
|
58
70
|
throw new Error(`Pending source receipt escapes workspace: ${relative}`);
|
|
@@ -199,7 +211,7 @@ export async function discoverSourceFiles(cwd, options = {}) {
|
|
|
199
211
|
const recoveredPendingReceiptPaths = [];
|
|
200
212
|
if (options.trackedOnly) {
|
|
201
213
|
const tracked = await gitTrackedPaths(cwd);
|
|
202
|
-
const pending = pendingSourcePaths(cwd, options.recoverMissingPendingSources === true);
|
|
214
|
+
const pending = pendingSourcePaths(cwd, options.recoverMissingPendingSources === true, tracked);
|
|
203
215
|
recoveredPendingReceiptPaths.push(...pending.recoveredReceipts);
|
|
204
216
|
entityMarkdownFiles = filterTracked(cwd, entityMarkdownFiles, tracked, new Set(pending.paths.keys()));
|
|
205
217
|
manifestFiles = filterTracked(cwd, manifestFiles, tracked, new Set(pending.paths.keys()));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/extractors/markdown.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/extractors/markdown.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,7 +20,7 @@ import { readFileSync } from "node:fs";
|
|
|
20
20
|
import Ajv from "ajv";
|
|
21
21
|
import { load as yamlLoad } from "js-yaml";
|
|
22
22
|
import { withoutContextSections } from "../entity-body-context.js";
|
|
23
|
-
import { semanticClaimKey } from "../operations/semantic-advisor/clauses.js";
|
|
23
|
+
import { deriveFactClaimKey, semanticClaimKey, } from "../operations/semantic-advisor/clauses.js";
|
|
24
24
|
import { normalizeEntityOrigin, } from "../public/entity-origin.js";
|
|
25
25
|
import { PROOF_BINDINGS_SCHEMA, PROOF_CONTRACT_SCHEMA, } from "../public/proof-protocol.js";
|
|
26
26
|
import { proofReceiptHistoryErrors, } from "../public/proof-receipt.js";
|
|
@@ -671,6 +671,7 @@ function extractFromMarkdownContent(content, filePath) {
|
|
|
671
671
|
hint: "Fix the entity fields so they match the public schema.",
|
|
672
672
|
});
|
|
673
673
|
}
|
|
674
|
+
deriveFactClaimKey(entity);
|
|
674
675
|
if (entity.type === "fact" &&
|
|
675
676
|
entity.claim_key !== undefined &&
|
|
676
677
|
entity.claim_text !== undefined) {
|
|
@@ -47,7 +47,11 @@ export declare function withTopLevelField(content: string, key: string, value: s
|
|
|
47
47
|
* change (the key gone, every other key parsing identically).
|
|
48
48
|
*/
|
|
49
49
|
export declare function withoutTopLevelField(content: string, key: string): string | null;
|
|
50
|
-
/**
|
|
50
|
+
/**
|
|
51
|
+
* Replace a file's bytes atomically. A migration rewrite of an untracked
|
|
52
|
+
* `.kb/` source also rebinds its pending-source receipt, so the next sync
|
|
53
|
+
* reads the rewritten file instead of refusing it as hash drift.
|
|
54
|
+
*/
|
|
51
55
|
export declare function writeFileAtomically(filePath: string, content: string): void;
|
|
52
56
|
export declare function readText(filePath: string): string | null;
|
|
53
57
|
//# sourceMappingURL=kb-sources.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kb-sources.d.ts","sourceRoot":"","sources":["../../../src/operations/migration/kb-sources.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"kb-sources.d.ts","sourceRoot":"","sources":["../../../src/operations/migration/kb-sources.ts"],"names":[],"mappings":"AA+BA,OAAO,EAEL,KAAK,UAAU,EAEhB,MAAM,yBAAyB,CAAC;AAGjC,yEAAyE;AAEzE,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,IAAI,EAAE,UAAU,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC,CAAC;AAuBH,0EAA0E;AAE1E,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,SAAS,UAAU,EAAiB,GAC1C,gBAAgB,EAAE,CAkBpB;AAED,6DAA6D;AAE7D,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,IAAI,GAAG,MAAM,CAAC;CACpB,CAAC,CAAC;AAEH;;;;;GAKG;AAEH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAczE;AAUD;;;;;GAKG;AAEH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAe3E;AAeD;;;;;GAKG;AAEH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GACZ,MAAM,GAAG,IAAI,CAyBf;AAQD;;;;;;GAMG;AAEH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,IAAI,CAsBf;AAID;;;;GAIG;AAEH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAY3E;AAqBD,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMxD"}
|
|
@@ -15,11 +15,13 @@
|
|
|
15
15
|
You should have received a copy of the GNU Affero General Public License
|
|
16
16
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
*/
|
|
18
|
+
import { createHash } from "node:crypto";
|
|
18
19
|
import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, writeFileSync, } from "node:fs";
|
|
19
20
|
import path from "node:path";
|
|
20
21
|
import { isDeepStrictEqual } from "node:util";
|
|
21
22
|
import { load as loadYaml } from "js-yaml";
|
|
22
23
|
import { ENTITY_LANES, KB_PATHS, } from "../../utils/kb-paths.js";
|
|
24
|
+
import { republishPendingSourceReceipt } from "../mutation/source-authoring.js";
|
|
23
25
|
function walkMarkdown(directory, files) {
|
|
24
26
|
let entries;
|
|
25
27
|
try {
|
|
@@ -214,13 +216,38 @@ export function withoutTopLevelField(content, key) {
|
|
|
214
216
|
}
|
|
215
217
|
return match === null ? content : `${slice.prefix}${text}${slice.suffix}`;
|
|
216
218
|
}
|
|
217
|
-
|
|
219
|
+
const KB_ROOT_DIRNAME = ".kb";
|
|
220
|
+
/**
|
|
221
|
+
* Replace a file's bytes atomically. A migration rewrite of an untracked
|
|
222
|
+
* `.kb/` source also rebinds its pending-source receipt, so the next sync
|
|
223
|
+
* reads the rewritten file instead of refusing it as hash drift.
|
|
224
|
+
*/
|
|
218
225
|
// implements REQ-cli-schema-migration
|
|
219
226
|
export function writeFileAtomically(filePath, content) {
|
|
220
227
|
mkdirSync(path.dirname(filePath), { recursive: true });
|
|
221
228
|
const tempPath = `${filePath}.kibi-migrate-${process.pid}-${Date.now()}`;
|
|
222
229
|
writeFileSync(tempPath, content, "utf8");
|
|
223
230
|
renameSync(tempPath, filePath);
|
|
231
|
+
const source = kbSourceLocation(filePath);
|
|
232
|
+
if (source === null)
|
|
233
|
+
return;
|
|
234
|
+
republishPendingSourceReceipt(source.workspaceRoot, source.relativePath, createHash("sha256").update(content, "utf8").digest("hex"));
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* The workspace root and workspace-relative path of a file under `.kb/`, or
|
|
238
|
+
* `null` for a file outside any knowledge root.
|
|
239
|
+
*/
|
|
240
|
+
function kbSourceLocation(filePath) {
|
|
241
|
+
const absolute = path.resolve(filePath);
|
|
242
|
+
const segments = absolute.split(path.sep);
|
|
243
|
+
const index = segments.lastIndexOf(KB_ROOT_DIRNAME);
|
|
244
|
+
if (index <= 0)
|
|
245
|
+
return null;
|
|
246
|
+
const workspaceRoot = segments.slice(0, index).join(path.sep) || path.sep;
|
|
247
|
+
return {
|
|
248
|
+
workspaceRoot,
|
|
249
|
+
relativePath: segments.slice(index).join("/"),
|
|
250
|
+
};
|
|
224
251
|
}
|
|
225
252
|
// implements REQ-cli-schema-migration
|
|
226
253
|
export function readText(filePath) {
|
|
@@ -26,6 +26,14 @@ export declare function restoreFileTimes(absolutePath: string, times: FileTimes
|
|
|
26
26
|
* removed file makes every later sync fail on a missing pending source.
|
|
27
27
|
*/
|
|
28
28
|
export declare function retirePendingSourceReceipt(workspaceRoot: string, relativePath: string): void;
|
|
29
|
+
/**
|
|
30
|
+
* Rebind the pending receipt of an untracked source that a migration rewrote
|
|
31
|
+
* in place. A receipt pins the file to exact bytes; a rewrite that leaves the
|
|
32
|
+
* old hash behind makes every later sync refuse the file as "hash drift", so
|
|
33
|
+
* a migration republishes the receipt it finds, and leaves a file without
|
|
34
|
+
* one alone (tracked sources carry no receipt). Returns whether one existed.
|
|
35
|
+
*/
|
|
36
|
+
export declare function republishPendingSourceReceipt(workspaceRoot: string, relativePath: string, afterHash: string): boolean;
|
|
29
37
|
export declare function resolveContainedSourcePath(workspaceRoot: string, relative: string): string;
|
|
30
38
|
export declare function normalizeAuthoredSourcePath(workspaceRoot: string, source: string): string;
|
|
31
39
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"source-authoring.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/source-authoring.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAOjF,OAAO,KAAK,EAAqB,WAAW,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC,CAAC;AAmBH,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,GAChB,IAAI,CAiBN;AAED,KAAK,SAAS,GAAG,QAAQ,CAAC;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,CAAC,CAAC;AAExD,8EAA8E;AAE9E,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAOpE;AAED;;;;GAIG;AAEH,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,SAAS,GAAG,IAAI,GACtB,IAAI,CAON;AAeD;;;;GAIG;AAEH,wBAAgB,0BAA0B,CACxC,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,GACnB,IAAI,CAMN;AAgBD,wBAAgB,0BAA0B,CACxC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,MAAM,CAqCR;AAED,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,GACb,MAAM,CAoBR;AAsBD;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CAYpB;AAED,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,GACX,OAAO,CAET;AAkGD,uFAAuF;AAEvF,eAAO,MAAM,uBAAuB,uGAM1B,CAAC;AA8BX,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,OAAO,GACZ,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAiCzC;AAwRD,wBAAgB,oBAAoB,CAClC,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,GACtB;IAAE,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CA6C7C;AAED;;;;;;;GAOG;AACH,wBAAgB,kCAAkC,CAChD,eAAe,EAAE,MAAM,EACvB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,GAC7D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CA4DpC;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAC5C,eAAe,EAAE,MAAM,EACvB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,GAC7D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAiEpC;AAED;;;;GAIG;AAEH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,YAAY,EAAE,MAAM,GACnB,MAAM,CAsBR;AAED;;;;;;;GAOG;AAEH,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,OAAO,CAaT;AAED,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAC5C,OAAO,CAAC,EAAE,gBAAgB,EAC1B,sBAAsB,CAAC,EAAE,MAAM,GAC9B,OAAO,CAAC;IACT,OAAO,EAAE,kBAAkB,CAAC;IAC5B,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B,GAAG,IAAI,CAAC,CA+IR;AAED,uEAAuE;AACvE,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAC3C,MAAM,CAOR"}
|
|
1
|
+
{"version":3,"file":"source-authoring.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/source-authoring.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAOjF,OAAO,KAAK,EAAqB,WAAW,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC,CAAC;AAmBH,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,GAChB,IAAI,CAiBN;AAED,KAAK,SAAS,GAAG,QAAQ,CAAC;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,CAAC,CAAC;AAExD,8EAA8E;AAE9E,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAOpE;AAED;;;;GAIG;AAEH,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,SAAS,GAAG,IAAI,GACtB,IAAI,CAON;AAeD;;;;GAIG;AAEH,wBAAgB,0BAA0B,CACxC,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,GACnB,IAAI,CAMN;AAED;;;;;;GAMG;AAEH,wBAAgB,6BAA6B,CAC3C,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,GAChB,OAAO,CA8BT;AAgBD,wBAAgB,0BAA0B,CACxC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,MAAM,CAqCR;AAED,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,GACb,MAAM,CAoBR;AAsBD;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CAYpB;AAED,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,GACX,OAAO,CAET;AAkGD,uFAAuF;AAEvF,eAAO,MAAM,uBAAuB,uGAM1B,CAAC;AA8BX,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,OAAO,GACZ,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAiCzC;AAwRD,wBAAgB,oBAAoB,CAClC,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,GACtB;IAAE,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CA6C7C;AAED;;;;;;;GAOG;AACH,wBAAgB,kCAAkC,CAChD,eAAe,EAAE,MAAM,EACvB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,GAC7D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CA4DpC;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAC5C,eAAe,EAAE,MAAM,EACvB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,GAC7D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAiEpC;AAED;;;;GAIG;AAEH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,YAAY,EAAE,MAAM,GACnB,MAAM,CAsBR;AAED;;;;;;;GAOG;AAEH,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,OAAO,CAaT;AAED,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAC5C,OAAO,CAAC,EAAE,gBAAgB,EAC1B,sBAAsB,CAAC,EAAE,MAAM,GAC9B,OAAO,CAAC;IACT,OAAO,EAAE,kBAAkB,CAAC;IAC5B,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B,GAAG,IAAI,CAAC,CA+IR;AAED,uEAAuE;AACvE,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAC3C,MAAM,CAOR"}
|
|
@@ -82,6 +82,39 @@ export function retirePendingSourceReceipt(workspaceRoot, relativePath) {
|
|
|
82
82
|
throw error;
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Rebind the pending receipt of an untracked source that a migration rewrote
|
|
87
|
+
* in place. A receipt pins the file to exact bytes; a rewrite that leaves the
|
|
88
|
+
* old hash behind makes every later sync refuse the file as "hash drift", so
|
|
89
|
+
* a migration republishes the receipt it finds, and leaves a file without
|
|
90
|
+
* one alone (tracked sources carry no receipt). Returns whether one existed.
|
|
91
|
+
*/
|
|
92
|
+
// implements REQ-cli-schema-migration, REQ-core-atomic-upsert-persistence
|
|
93
|
+
export function republishPendingSourceReceipt(workspaceRoot, relativePath, afterHash) {
|
|
94
|
+
const receiptPath = pendingReceiptPath(workspaceRoot, relativePath);
|
|
95
|
+
const raw = readPendingSourceReceiptBytes(receiptPath);
|
|
96
|
+
if (raw === null)
|
|
97
|
+
return false;
|
|
98
|
+
let receipt;
|
|
99
|
+
try {
|
|
100
|
+
const parsed = JSON.parse(raw);
|
|
101
|
+
receipt =
|
|
102
|
+
parsed !== null && typeof parsed === "object"
|
|
103
|
+
? parsed
|
|
104
|
+
: {};
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
receipt = {};
|
|
108
|
+
}
|
|
109
|
+
fs.writeFileSync(receiptPath, `${JSON.stringify({
|
|
110
|
+
version: 1,
|
|
111
|
+
...receipt,
|
|
112
|
+
path: relativePath,
|
|
113
|
+
afterHash,
|
|
114
|
+
rebasedAt: new Date().toISOString(),
|
|
115
|
+
}, null, 2)}\n`, { mode: 0o600 });
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
85
118
|
/**
|
|
86
119
|
* Authored YAML round-trips keep long scalars on one line, matching sync and
|
|
87
120
|
* coordinate refresh output, so editing one entry never refolds the others.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/validation.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,0BAA0B,EAC3B,MAAM,oCAAoC,CAAC;
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/validation.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,0BAA0B,EAC3B,MAAM,oCAAoC,CAAC;AAU5C,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAqI/D,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,IAAI,GACR,eAAe,CA6DjB;AAED,OAAO,EAAE,0BAA0B,EAAE,CAAC"}
|
|
@@ -4,7 +4,7 @@ import entitySchema from "../../public/schemas/entity.js";
|
|
|
4
4
|
import relationshipSchema from "../../public/schemas/relationship.js";
|
|
5
5
|
// implements REQ-kibi-operation-interface-parity
|
|
6
6
|
import { SYMBOL_ROLES, isAllowedGranularityReason, } from "../../public/symbol-granularity.js";
|
|
7
|
-
import { semanticClaimKey } from "../semantic-advisor/clauses.js";
|
|
7
|
+
import { deriveFactClaimKey, semanticClaimKey, } from "../semantic-advisor/clauses.js";
|
|
8
8
|
import { factKindShapeHints, validateFactModelingShape, valueFieldHint, } from "./strict-fact.js";
|
|
9
9
|
const ajv = new Ajv({ strict: false });
|
|
10
10
|
const schema = entitySchema;
|
|
@@ -128,6 +128,7 @@ export function validateUpsertInput(input, now) {
|
|
|
128
128
|
if (!validateEntity(entity)) {
|
|
129
129
|
throw new Error(`Entity validation failed: ${formatEntityErrors(entity, validateEntity.errors ?? [])}`);
|
|
130
130
|
}
|
|
131
|
+
deriveFactClaimKey(entity);
|
|
131
132
|
validateSymbolSourceFile(entity);
|
|
132
133
|
validateProofExemptionPairing(entity);
|
|
133
134
|
if (entity.type === "test" && Array.isArray(entity.proof_receipts)) {
|
|
@@ -9,5 +9,14 @@ export declare function hasNormativeAssertion(text: string): boolean;
|
|
|
9
9
|
export declare function modeledClaimRole(text: string, modality?: string): "normative" | "descriptive";
|
|
10
10
|
export declare function normalizeSemanticClause(value: string): string;
|
|
11
11
|
export declare function semanticClaimKey(text: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Fill `claim_key` from `claim_text` on a fact that may ground a claim.
|
|
14
|
+
*
|
|
15
|
+
* The key is a pure function of the text, so a caller that sends the text
|
|
16
|
+
* alone has given Kibi everything it needs; a supplied key is still checked
|
|
17
|
+
* against the derived one by the entity validators. Observation and meta
|
|
18
|
+
* facts quote a claim without owning it, so they stay keyless.
|
|
19
|
+
*/
|
|
20
|
+
export declare function deriveFactClaimKey(entity: Record<string, unknown>): void;
|
|
12
21
|
export declare function extractSemanticClauses(text: string, suppliedClauses?: readonly string[]): readonly SemanticClause[];
|
|
13
22
|
//# sourceMappingURL=clauses.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clauses.d.ts","sourceRoot":"","sources":["../../../src/operations/semantic-advisor/clauses.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,UAAU,GAAG,UAAU,CAAC;CACjC,CAAC,CAAC;AAmBH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D;AAQD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,GAChB,WAAW,GAAG,aAAa,CAG7B;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAW7D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIrD;AA4BD,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,GAClC,SAAS,cAAc,EAAE,CA4B3B"}
|
|
1
|
+
{"version":3,"file":"clauses.d.ts","sourceRoot":"","sources":["../../../src/operations/semantic-advisor/clauses.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,UAAU,GAAG,UAAU,CAAC;CACjC,CAAC,CAAC;AAmBH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D;AAQD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,GAChB,WAAW,GAAG,aAAa,CAG7B;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAW7D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIrD;AAKD;;;;;;;GAOG;AAEH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAWxE;AA4BD,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,GAClC,SAAS,cAAc,EAAE,CA4B3B"}
|
|
@@ -38,6 +38,30 @@ export function semanticClaimKey(text) {
|
|
|
38
38
|
const digest = createHash("sha256").update(normalized).digest("hex");
|
|
39
39
|
return `CLAIM-${digest.slice(0, 16).toUpperCase()}`;
|
|
40
40
|
}
|
|
41
|
+
/** Fact kinds that quote a claim as a review note and never ground it. */
|
|
42
|
+
const NON_GROUNDING_FACT_KINDS = new Set(["observation", "meta"]);
|
|
43
|
+
/**
|
|
44
|
+
* Fill `claim_key` from `claim_text` on a fact that may ground a claim.
|
|
45
|
+
*
|
|
46
|
+
* The key is a pure function of the text, so a caller that sends the text
|
|
47
|
+
* alone has given Kibi everything it needs; a supplied key is still checked
|
|
48
|
+
* against the derived one by the entity validators. Observation and meta
|
|
49
|
+
* facts quote a claim without owning it, so they stay keyless.
|
|
50
|
+
*/
|
|
51
|
+
// implements REQ-kibi-review-observation-claim-text-v2
|
|
52
|
+
export function deriveFactClaimKey(entity) {
|
|
53
|
+
if (entity.type !== "fact")
|
|
54
|
+
return;
|
|
55
|
+
if (entity.claim_key !== undefined)
|
|
56
|
+
return;
|
|
57
|
+
if (typeof entity.claim_text !== "string")
|
|
58
|
+
return;
|
|
59
|
+
if (typeof entity.fact_kind === "string" &&
|
|
60
|
+
NON_GROUNDING_FACT_KINDS.has(entity.fact_kind)) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
entity.claim_key = semanticClaimKey(entity.claim_text);
|
|
64
|
+
}
|
|
41
65
|
function detectedClauses(text) {
|
|
42
66
|
return text
|
|
43
67
|
.split(/(?:\r?\n)+|;|(?<=[.!?])\s+(?=[A-Z0-9])/)
|
|
@@ -1521,11 +1521,11 @@ export declare const OPERATION_CATALOG: readonly [{
|
|
|
1521
1521
|
readonly claim_key: {
|
|
1522
1522
|
readonly type: "string";
|
|
1523
1523
|
readonly pattern: "^CLAIM-[A-F0-9]{16}$";
|
|
1524
|
-
readonly description: "Stable
|
|
1524
|
+
readonly description: "Stable key of the atomic prose clause grounded by this fact, derived from claim_text. Optional: when omitted, Kibi derives it; when sent, it must equal the derived key.";
|
|
1525
1525
|
};
|
|
1526
1526
|
readonly claim_text: {
|
|
1527
1527
|
readonly type: "string";
|
|
1528
|
-
readonly description: "Exact atomic requirement clause represented by this fact, retained for human audit.
|
|
1528
|
+
readonly description: "Exact atomic requirement clause represented by this fact, retained for human audit. On a grounding fact Kibi derives claim_key from it; an observation or meta fact quotes the clause it is about without a key.";
|
|
1529
1529
|
};
|
|
1530
1530
|
readonly predicate_name: {
|
|
1531
1531
|
readonly type: "string";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration-plan.d.ts","sourceRoot":"","sources":["../../../src/public/operations/migration-plan.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"migration-plan.d.ts","sourceRoot":"","sources":["../../../src/public/operations/migration-plan.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { existsSync, readFileSync } from "node:fs";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
+
import { planLegacyStorageMigration } from "../../commands/legacy-storage-migration.js";
|
|
4
5
|
import { BRANCH_STORE_NOT_COMPILED } from "../../utils/branch-store.js";
|
|
5
6
|
import { legacyConfigExists } from "../../utils/config.js";
|
|
6
7
|
import { MTIME_SOURCE_REASON_CODES } from "../../utils/content-freshness.js";
|
|
@@ -488,6 +489,13 @@ export function buildActionsFromStatus(input) {
|
|
|
488
489
|
}
|
|
489
490
|
const storeState = typeof store?.state === "string" ? store.state : null;
|
|
490
491
|
const legacyStorageMigrationRequired = legacyConfigExists(input.workspaceRoot);
|
|
492
|
+
// A legacy cutover that cannot move its files (a destination already
|
|
493
|
+
// exists, a malformed config) is an operator decision, not an automatic
|
|
494
|
+
// step that fails when applied and takes the compile with it.
|
|
495
|
+
const legacyStorage = legacyStorageMigrationRequired
|
|
496
|
+
? planLegacyStorageMigration(input.workspaceRoot)
|
|
497
|
+
: null;
|
|
498
|
+
const legacyStorageBlocked = legacyStorage !== null && legacyStorage.blockers.length > 0;
|
|
491
499
|
if (storeState === "missing") {
|
|
492
500
|
actions.push(migrationAction({
|
|
493
501
|
id: "branch-store-ensure",
|
|
@@ -520,6 +528,7 @@ export function buildActionsFromStatus(input) {
|
|
|
520
528
|
}));
|
|
521
529
|
}
|
|
522
530
|
if (configStatus.needsMigration || legacyStorageMigrationRequired) {
|
|
531
|
+
const operatorOnly = configStatus.status === "newer" || legacyStorageBlocked;
|
|
523
532
|
actions.push(migrationAction({
|
|
524
533
|
id: "schema-config-upgrade",
|
|
525
534
|
code: configStatus.status === "invalid"
|
|
@@ -528,17 +537,34 @@ export function buildActionsFromStatus(input) {
|
|
|
528
537
|
? "legacy_storage_migration"
|
|
529
538
|
: "schema_version_upgrade",
|
|
530
539
|
category: "schema",
|
|
531
|
-
state:
|
|
532
|
-
safety:
|
|
533
|
-
invocation:
|
|
540
|
+
state: operatorOnly ? "blocked" : "ready",
|
|
541
|
+
safety: operatorOnly ? "operator" : "automatic",
|
|
542
|
+
invocation: legacyStorageBlocked
|
|
543
|
+
? {
|
|
544
|
+
kind: "review",
|
|
545
|
+
instruction: `The legacy .kb/config.json still names knowledge files outside .kb/ and Kibi cannot move them: ${legacyStorage?.blockers.join(" ")} Keep one copy of each conflicting file (the .kb/ one is what Kibi compiles), remove or git-rm the legacy copy, then run 'kibi migrate --yes' to retire .kb/config.json.`,
|
|
546
|
+
}
|
|
547
|
+
: { kind: "cli", command_argv: ["kibi", "migrate", "--yes"] },
|
|
534
548
|
affectedFiles: [
|
|
535
549
|
".kb/manifest.json",
|
|
536
550
|
".kb/migrations",
|
|
537
551
|
".kb/config.json",
|
|
552
|
+
...(legacyStorage?.moves.map((move) => move.from) ?? []),
|
|
538
553
|
],
|
|
539
|
-
evidence: {
|
|
554
|
+
evidence: {
|
|
555
|
+
configStatus,
|
|
556
|
+
...(legacyStorage === null
|
|
557
|
+
? {}
|
|
558
|
+
: {
|
|
559
|
+
legacyStorage: {
|
|
560
|
+
moves: legacyStorage.moves,
|
|
561
|
+
blockers: legacyStorage.blockers,
|
|
562
|
+
legacyConfig: legacyStorage.legacyConfig,
|
|
563
|
+
},
|
|
564
|
+
}),
|
|
565
|
+
},
|
|
540
566
|
dependsOn: storeState === "missing" ? ["branch-store-ensure"] : [],
|
|
541
|
-
autoApplicable:
|
|
567
|
+
autoApplicable: !operatorOnly,
|
|
542
568
|
}));
|
|
543
569
|
}
|
|
544
570
|
// implements REQ-cli-status-pre-first-sync
|
|
@@ -558,9 +584,13 @@ export function buildActionsFromStatus(input) {
|
|
|
558
584
|
typeof store?.path === "string" ? store.path : ".kb/branches",
|
|
559
585
|
],
|
|
560
586
|
evidence: { reason: uncompiled },
|
|
587
|
+
// A blocked schema step waits on an operator; the compile still runs
|
|
588
|
+
// from the .kb/ sources Kibi already reads.
|
|
561
589
|
dependsOn: actions
|
|
562
|
-
.
|
|
563
|
-
.
|
|
590
|
+
.filter((action) => action.state === "ready" &&
|
|
591
|
+
(action.id === "branch-store-ensure" ||
|
|
592
|
+
action.id === "schema-config-upgrade"))
|
|
593
|
+
.map((action) => action.id),
|
|
564
594
|
postconditions: [{ branchStore: "compiled" }],
|
|
565
595
|
autoApplicable: true,
|
|
566
596
|
}));
|
|
@@ -522,11 +522,11 @@ export declare const ENTITY_PROPERTIES_SCHEMA: {
|
|
|
522
522
|
readonly claim_key: {
|
|
523
523
|
readonly type: "string";
|
|
524
524
|
readonly pattern: "^CLAIM-[A-F0-9]{16}$";
|
|
525
|
-
readonly description: "Stable
|
|
525
|
+
readonly description: "Stable key of the atomic prose clause grounded by this fact, derived from claim_text. Optional: when omitted, Kibi derives it; when sent, it must equal the derived key.";
|
|
526
526
|
};
|
|
527
527
|
readonly claim_text: {
|
|
528
528
|
readonly type: "string";
|
|
529
|
-
readonly description: "Exact atomic requirement clause represented by this fact, retained for human audit.
|
|
529
|
+
readonly description: "Exact atomic requirement clause represented by this fact, retained for human audit. On a grounding fact Kibi derives claim_key from it; an observation or meta fact quotes the clause it is about without a key.";
|
|
530
530
|
};
|
|
531
531
|
readonly predicate_name: {
|
|
532
532
|
readonly type: "string";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mutation-schemas.d.ts","sourceRoot":"","sources":["../../../../src/public/operations/specs/mutation-schemas.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,YAAY,gFASf,CAAC;
|
|
1
|
+
{"version":3,"file":"mutation-schemas.d.ts","sourceRoot":"","sources":["../../../../src/public/operations/specs/mutation-schemas.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,YAAY,gFASf,CAAC;AAWX,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoX3B,CAAC;AAEX,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;CA8CvB,CAAC"}
|
|
@@ -11,22 +11,13 @@ export const ENTITY_TYPES = [
|
|
|
11
11
|
"symbol",
|
|
12
12
|
"fact",
|
|
13
13
|
];
|
|
14
|
-
//
|
|
15
|
-
//
|
|
14
|
+
// A claim_key names the clause in claim_text, so it never travels alone. The
|
|
15
|
+
// reverse is open: Kibi derives a missing claim_key from claim_text on a
|
|
16
|
+
// grounding fact, and an observation or meta fact quotes a claim without one.
|
|
17
|
+
// implements REQ-kibi-review-observation-claim-text-v2
|
|
16
18
|
const CLAIM_PROVENANCE_CONDITIONAL = JSON.parse(`{
|
|
17
|
-
"if": {
|
|
18
|
-
|
|
19
|
-
{ "required": ["claim_key"] },
|
|
20
|
-
{
|
|
21
|
-
"required": ["claim_text"],
|
|
22
|
-
"not": {
|
|
23
|
-
"properties": { "fact_kind": { "enum": ["observation", "meta"] } },
|
|
24
|
-
"required": ["fact_kind"]
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
]
|
|
28
|
-
},
|
|
29
|
-
"then": { "required": ["claim_key", "claim_text"] }
|
|
19
|
+
"if": { "required": ["claim_key"] },
|
|
20
|
+
"then": { "required": ["claim_text"] }
|
|
30
21
|
}`);
|
|
31
22
|
export const ENTITY_PROPERTIES_SCHEMA = {
|
|
32
23
|
type: "object",
|
|
@@ -251,11 +242,11 @@ export const ENTITY_PROPERTIES_SCHEMA = {
|
|
|
251
242
|
claim_key: {
|
|
252
243
|
type: "string",
|
|
253
244
|
pattern: "^CLAIM-[A-F0-9]{16}$",
|
|
254
|
-
description: "Stable
|
|
245
|
+
description: "Stable key of the atomic prose clause grounded by this fact, derived from claim_text. Optional: when omitted, Kibi derives it; when sent, it must equal the derived key.",
|
|
255
246
|
},
|
|
256
247
|
claim_text: {
|
|
257
248
|
type: "string",
|
|
258
|
-
description: "Exact atomic requirement clause represented by this fact, retained for human audit.
|
|
249
|
+
description: "Exact atomic requirement clause represented by this fact, retained for human audit. On a grounding fact Kibi derives claim_key from it; an observation or meta fact quotes the clause it is about without a key.",
|
|
259
250
|
},
|
|
260
251
|
predicate_name: {
|
|
261
252
|
type: "string",
|
|
@@ -539,11 +539,11 @@ export declare const upsertSpec: {
|
|
|
539
539
|
readonly claim_key: {
|
|
540
540
|
readonly type: "string";
|
|
541
541
|
readonly pattern: "^CLAIM-[A-F0-9]{16}$";
|
|
542
|
-
readonly description: "Stable
|
|
542
|
+
readonly description: "Stable key of the atomic prose clause grounded by this fact, derived from claim_text. Optional: when omitted, Kibi derives it; when sent, it must equal the derived key.";
|
|
543
543
|
};
|
|
544
544
|
readonly claim_text: {
|
|
545
545
|
readonly type: "string";
|
|
546
|
-
readonly description: "Exact atomic requirement clause represented by this fact, retained for human audit.
|
|
546
|
+
readonly description: "Exact atomic requirement clause represented by this fact, retained for human audit. On a grounding fact Kibi derives claim_key from it; an observation or meta fact quotes the clause it is about without a key.";
|
|
547
547
|
};
|
|
548
548
|
readonly predicate_name: {
|
|
549
549
|
readonly type: "string";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../../../src/public/schemas/entity.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../../../src/public/schemas/entity.ts"],"names":[],"mappings":"AAwTA,QAAA,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CA4ZzC,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -22,19 +22,8 @@ import { PROOF_RECEIPT_SCHEMA } from "../proof-receipt.js";
|
|
|
22
22
|
import { SYMBOL_ROLES } from "../symbol-granularity.js";
|
|
23
23
|
const factConditionals = JSON.parse(`[
|
|
24
24
|
{
|
|
25
|
-
"if": {
|
|
26
|
-
|
|
27
|
-
{ "required": ["claim_key"] },
|
|
28
|
-
{
|
|
29
|
-
"required": ["claim_text"],
|
|
30
|
-
"not": {
|
|
31
|
-
"properties": { "fact_kind": { "enum": ["observation", "meta"] } },
|
|
32
|
-
"required": ["fact_kind"]
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
]
|
|
36
|
-
},
|
|
37
|
-
"then": { "required": ["claim_key", "claim_text"] }
|
|
25
|
+
"if": { "required": ["claim_key"] },
|
|
26
|
+
"then": { "required": ["claim_text"] }
|
|
38
27
|
},
|
|
39
28
|
{
|
|
40
29
|
"if": {
|
|
@@ -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.15.
|
|
5
|
+
version: 2.15.3
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -369,6 +369,8 @@ For each relational clause, call `kb_model` with `mode: "predicates"`, that clau
|
|
|
369
369
|
reviewed `schemaId`. If `binding_status` is `incomplete`, supply
|
|
370
370
|
`argumentBindings` and retry. Persist `fact_kind: predicate` with the same
|
|
371
371
|
`claim_key` / `claim_text`, then link `REQ -> fact` with `requires_predicate`.
|
|
372
|
+
`claim_key` is derived from `claim_text`, so a ground fact may send the exact
|
|
373
|
+
clause alone and Kibi fills the key in; a sent key must equal the derived one.
|
|
372
374
|
Use `kb_model` with `mode: "requirement"` for strict scalar clauses. Use
|
|
373
375
|
`fact_kind: observation` only for a true ontology gap. The manifest is not
|
|
374
376
|
grounding: run `logic-coverage` so each key binds to one ground fact.
|
|
@@ -6,7 +6,7 @@ Requirement prose remains the human-readable source. Facts add queryable semanti
|
|
|
6
6
|
|
|
7
7
|
Logical coverage is clause-based, not entity-based. Give `kb_model` (`mode: "analyze"`) the complete requirement body and verify that its `clauses` list contains every atomic obligation. Supply the `clauses` input yourself when automatic splitting would combine or omit obligations. For every normative clause:
|
|
8
8
|
|
|
9
|
-
-
|
|
9
|
+
- put the exact clause as `claim_text` on its ground fact, with the returned stable key as `claim_key` or none (Kibi derives a missing key; a sent key must match);
|
|
10
10
|
- add the key to the exact current `logic_claims` set, removing only stale keys whose propositions no longer exist in the source;
|
|
11
11
|
- link it through exactly one `requires_property` for `property_value`, one `requires_predicate` for `predicate`, or one `requires_rule` for a safe `rule` fact;
|
|
12
12
|
- leave ambiguity and ontology gaps visibly unresolved—observations do not satisfy `logic-coverage`.
|
|
@@ -126,8 +126,8 @@ diagnostics (`symbol_semantic_review_needed`).
|
|
|
126
126
|
`requires_predicate`.
|
|
127
127
|
3. Scalar placement/alignment/order clauses: `kb_model` (`mode: "requirement"`), apply the strict
|
|
128
128
|
subject/property plan and `constrains` / `requires_property`.
|
|
129
|
-
4. Preserve `claim_key` / `claim_text
|
|
130
|
-
`logic_claims` manifest.
|
|
129
|
+
4. Preserve `claim_key` / `claim_text` (a missing key is derived from the
|
|
130
|
+
text); merge every key into the requirement `logic_claims` manifest.
|
|
131
131
|
5. `kb_upsert` with `dryRun: true`, create endpoints first, then sequential `kb_upsert`.
|
|
132
132
|
6. `kb_check` with `logic-coverage`, `predicate-verifiability`, `domain-contradictions`,
|
|
133
133
|
then a final unfiltered `kb_check`.
|
|
@@ -203,7 +203,7 @@ Optional per-project workflow for recording what the screen should look like. No
|
|
|
203
203
|
2. Run `kb_model` with `mode: "analyze"` on the description; audit or supply `clauses`.
|
|
204
204
|
3. For relational layout clauses ("X must remain visually aligned with Y"), call `kb_model` with `mode: "predicates"`, apply the returned `fact_kind: predicate` plan with `predicate_name: visual_layout_rule` and `requires_predicate`.
|
|
205
205
|
4. For scalar placement, alignment, and ordering clauses, call `kb_model` with `mode: "requirement"` and apply strict `fact_kind: subject` / `fact_kind: property_value` facts linked with `constrains` / `requires_property`. Model header order as indexed property keys (`nav_order_1`, `nav_order_2`, ...) against one subject region.
|
|
206
|
-
5. Preserve `claim_key` / `claim_text` on every ground fact and merge every key into the requirement `logic_claims` manifest.
|
|
206
|
+
5. Preserve `claim_key` / `claim_text` on every ground fact (a missing `claim_key` is derived from `claim_text`) and merge every key into the requirement `logic_claims` manifest.
|
|
207
207
|
6. Model UI components as `symbol` entities with `sourceFile` and `symbol_role: behavioral`, linked `implements` to the requirement.
|
|
208
208
|
7. `kb_upsert` with `dryRun: true`, create endpoints first, then sequential `kb_upsert`. Run `kb_check` with `logic-coverage`, `predicate-verifiability`, and `domain-contradictions`, then a final unfiltered `kb_check`.
|
|
209
209
|
|
|
@@ -1675,35 +1675,12 @@
|
|
|
1675
1675
|
},
|
|
1676
1676
|
{
|
|
1677
1677
|
"if": {
|
|
1678
|
-
"
|
|
1679
|
-
|
|
1680
|
-
"required": [
|
|
1681
|
-
"claim_key"
|
|
1682
|
-
]
|
|
1683
|
-
},
|
|
1684
|
-
{
|
|
1685
|
-
"required": [
|
|
1686
|
-
"claim_text"
|
|
1687
|
-
],
|
|
1688
|
-
"not": {
|
|
1689
|
-
"properties": {
|
|
1690
|
-
"fact_kind": {
|
|
1691
|
-
"enum": [
|
|
1692
|
-
"observation",
|
|
1693
|
-
"meta"
|
|
1694
|
-
]
|
|
1695
|
-
}
|
|
1696
|
-
},
|
|
1697
|
-
"required": [
|
|
1698
|
-
"fact_kind"
|
|
1699
|
-
]
|
|
1700
|
-
}
|
|
1701
|
-
}
|
|
1678
|
+
"required": [
|
|
1679
|
+
"claim_key"
|
|
1702
1680
|
]
|
|
1703
1681
|
},
|
|
1704
1682
|
"then": {
|
|
1705
1683
|
"required": [
|
|
1706
|
-
"claim_key",
|
|
1707
1684
|
"claim_text"
|
|
1708
1685
|
]
|
|
1709
1686
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { existsSync, readFileSync } from "node:fs";
|
|
3
3
|
import * as path from "node:path";
|
|
4
|
+
import { planLegacyStorageMigration } from "../../commands/legacy-storage-migration.js";
|
|
4
5
|
import { BRANCH_STORE_NOT_COMPILED } from "../../utils/branch-store.js";
|
|
5
6
|
import { legacyConfigExists } from "../../utils/config.js";
|
|
6
7
|
import { MTIME_SOURCE_REASON_CODES } from "../../utils/content-freshness.js";
|
|
@@ -688,6 +689,14 @@ export function buildActionsFromStatus(input: {
|
|
|
688
689
|
const legacyStorageMigrationRequired = legacyConfigExists(
|
|
689
690
|
input.workspaceRoot,
|
|
690
691
|
);
|
|
692
|
+
// A legacy cutover that cannot move its files (a destination already
|
|
693
|
+
// exists, a malformed config) is an operator decision, not an automatic
|
|
694
|
+
// step that fails when applied and takes the compile with it.
|
|
695
|
+
const legacyStorage = legacyStorageMigrationRequired
|
|
696
|
+
? planLegacyStorageMigration(input.workspaceRoot)
|
|
697
|
+
: null;
|
|
698
|
+
const legacyStorageBlocked =
|
|
699
|
+
legacyStorage !== null && legacyStorage.blockers.length > 0;
|
|
691
700
|
if (storeState === "missing") {
|
|
692
701
|
actions.push(
|
|
693
702
|
migrationAction({
|
|
@@ -724,6 +733,8 @@ export function buildActionsFromStatus(input: {
|
|
|
724
733
|
}
|
|
725
734
|
|
|
726
735
|
if (configStatus.needsMigration || legacyStorageMigrationRequired) {
|
|
736
|
+
const operatorOnly =
|
|
737
|
+
configStatus.status === "newer" || legacyStorageBlocked;
|
|
727
738
|
actions.push(
|
|
728
739
|
migrationAction({
|
|
729
740
|
id: "schema-config-upgrade",
|
|
@@ -734,17 +745,34 @@ export function buildActionsFromStatus(input: {
|
|
|
734
745
|
? "legacy_storage_migration"
|
|
735
746
|
: "schema_version_upgrade",
|
|
736
747
|
category: "schema",
|
|
737
|
-
state:
|
|
738
|
-
safety:
|
|
739
|
-
invocation:
|
|
748
|
+
state: operatorOnly ? "blocked" : "ready",
|
|
749
|
+
safety: operatorOnly ? "operator" : "automatic",
|
|
750
|
+
invocation: legacyStorageBlocked
|
|
751
|
+
? {
|
|
752
|
+
kind: "review",
|
|
753
|
+
instruction: `The legacy .kb/config.json still names knowledge files outside .kb/ and Kibi cannot move them: ${legacyStorage?.blockers.join(" ")} Keep one copy of each conflicting file (the .kb/ one is what Kibi compiles), remove or git-rm the legacy copy, then run 'kibi migrate --yes' to retire .kb/config.json.`,
|
|
754
|
+
}
|
|
755
|
+
: { kind: "cli", command_argv: ["kibi", "migrate", "--yes"] },
|
|
740
756
|
affectedFiles: [
|
|
741
757
|
".kb/manifest.json",
|
|
742
758
|
".kb/migrations",
|
|
743
759
|
".kb/config.json",
|
|
760
|
+
...(legacyStorage?.moves.map((move) => move.from) ?? []),
|
|
744
761
|
],
|
|
745
|
-
evidence: {
|
|
762
|
+
evidence: {
|
|
763
|
+
configStatus,
|
|
764
|
+
...(legacyStorage === null
|
|
765
|
+
? {}
|
|
766
|
+
: {
|
|
767
|
+
legacyStorage: {
|
|
768
|
+
moves: legacyStorage.moves,
|
|
769
|
+
blockers: legacyStorage.blockers,
|
|
770
|
+
legacyConfig: legacyStorage.legacyConfig,
|
|
771
|
+
},
|
|
772
|
+
}),
|
|
773
|
+
},
|
|
746
774
|
dependsOn: storeState === "missing" ? ["branch-store-ensure"] : [],
|
|
747
|
-
autoApplicable:
|
|
775
|
+
autoApplicable: !operatorOnly,
|
|
748
776
|
}),
|
|
749
777
|
);
|
|
750
778
|
}
|
|
@@ -769,12 +797,16 @@ export function buildActionsFromStatus(input: {
|
|
|
769
797
|
typeof store?.path === "string" ? store.path : ".kb/branches",
|
|
770
798
|
],
|
|
771
799
|
evidence: { reason: uncompiled },
|
|
800
|
+
// A blocked schema step waits on an operator; the compile still runs
|
|
801
|
+
// from the .kb/ sources Kibi already reads.
|
|
772
802
|
dependsOn: actions
|
|
773
|
-
.map((action) => action.id)
|
|
774
803
|
.filter(
|
|
775
|
-
(
|
|
776
|
-
|
|
777
|
-
|
|
804
|
+
(action) =>
|
|
805
|
+
action.state === "ready" &&
|
|
806
|
+
(action.id === "branch-store-ensure" ||
|
|
807
|
+
action.id === "schema-config-upgrade"),
|
|
808
|
+
)
|
|
809
|
+
.map((action) => action.id),
|
|
778
810
|
postconditions: [{ branchStore: "compiled" }],
|
|
779
811
|
autoApplicable: true,
|
|
780
812
|
}),
|
|
@@ -19,22 +19,13 @@ export const ENTITY_TYPES = [
|
|
|
19
19
|
"fact",
|
|
20
20
|
] as const;
|
|
21
21
|
|
|
22
|
-
//
|
|
23
|
-
//
|
|
22
|
+
// A claim_key names the clause in claim_text, so it never travels alone. The
|
|
23
|
+
// reverse is open: Kibi derives a missing claim_key from claim_text on a
|
|
24
|
+
// grounding fact, and an observation or meta fact quotes a claim without one.
|
|
25
|
+
// implements REQ-kibi-review-observation-claim-text-v2
|
|
24
26
|
const CLAIM_PROVENANCE_CONDITIONAL = JSON.parse(`{
|
|
25
|
-
"if": {
|
|
26
|
-
|
|
27
|
-
{ "required": ["claim_key"] },
|
|
28
|
-
{
|
|
29
|
-
"required": ["claim_text"],
|
|
30
|
-
"not": {
|
|
31
|
-
"properties": { "fact_kind": { "enum": ["observation", "meta"] } },
|
|
32
|
-
"required": ["fact_kind"]
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
]
|
|
36
|
-
},
|
|
37
|
-
"then": { "required": ["claim_key", "claim_text"] }
|
|
27
|
+
"if": { "required": ["claim_key"] },
|
|
28
|
+
"then": { "required": ["claim_text"] }
|
|
38
29
|
}`) as Record<string, unknown>;
|
|
39
30
|
|
|
40
31
|
export const ENTITY_PROPERTIES_SCHEMA = {
|
|
@@ -293,12 +284,12 @@ export const ENTITY_PROPERTIES_SCHEMA = {
|
|
|
293
284
|
type: "string",
|
|
294
285
|
pattern: "^CLAIM-[A-F0-9]{16}$",
|
|
295
286
|
description:
|
|
296
|
-
"Stable
|
|
287
|
+
"Stable key of the atomic prose clause grounded by this fact, derived from claim_text. Optional: when omitted, Kibi derives it; when sent, it must equal the derived key.",
|
|
297
288
|
},
|
|
298
289
|
claim_text: {
|
|
299
290
|
type: "string",
|
|
300
291
|
description:
|
|
301
|
-
"Exact atomic requirement clause represented by this fact, retained for human audit.
|
|
292
|
+
"Exact atomic requirement clause represented by this fact, retained for human audit. On a grounding fact Kibi derives claim_key from it; an observation or meta fact quotes the clause it is about without a key.",
|
|
302
293
|
},
|
|
303
294
|
predicate_name: {
|
|
304
295
|
type: "string",
|
|
@@ -42,19 +42,8 @@ type VerificationPerspective = "internal" | "consumer";
|
|
|
42
42
|
|
|
43
43
|
const factConditionals = JSON.parse(`[
|
|
44
44
|
{
|
|
45
|
-
"if": {
|
|
46
|
-
|
|
47
|
-
{ "required": ["claim_key"] },
|
|
48
|
-
{
|
|
49
|
-
"required": ["claim_text"],
|
|
50
|
-
"not": {
|
|
51
|
-
"properties": { "fact_kind": { "enum": ["observation", "meta"] } },
|
|
52
|
-
"required": ["fact_kind"]
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
]
|
|
56
|
-
},
|
|
57
|
-
"then": { "required": ["claim_key", "claim_text"] }
|
|
45
|
+
"if": { "required": ["claim_key"] },
|
|
46
|
+
"then": { "required": ["claim_text"] }
|
|
58
47
|
},
|
|
59
48
|
{
|
|
60
49
|
"if": {
|
|
@@ -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.15.
|
|
5
|
+
version: 2.15.3
|
|
6
6
|
kibiCompatibility: ">=1.0.0"
|
|
7
7
|
tags:
|
|
8
8
|
- kibi
|
|
@@ -369,6 +369,8 @@ For each relational clause, call `kb_model` with `mode: "predicates"`, that clau
|
|
|
369
369
|
reviewed `schemaId`. If `binding_status` is `incomplete`, supply
|
|
370
370
|
`argumentBindings` and retry. Persist `fact_kind: predicate` with the same
|
|
371
371
|
`claim_key` / `claim_text`, then link `REQ -> fact` with `requires_predicate`.
|
|
372
|
+
`claim_key` is derived from `claim_text`, so a ground fact may send the exact
|
|
373
|
+
clause alone and Kibi fills the key in; a sent key must equal the derived one.
|
|
372
374
|
Use `kb_model` with `mode: "requirement"` for strict scalar clauses. Use
|
|
373
375
|
`fact_kind: observation` only for a true ontology gap. The manifest is not
|
|
374
376
|
grounding: run `logic-coverage` so each key binds to one ground fact.
|
|
@@ -6,7 +6,7 @@ Requirement prose remains the human-readable source. Facts add queryable semanti
|
|
|
6
6
|
|
|
7
7
|
Logical coverage is clause-based, not entity-based. Give `kb_model` (`mode: "analyze"`) the complete requirement body and verify that its `clauses` list contains every atomic obligation. Supply the `clauses` input yourself when automatic splitting would combine or omit obligations. For every normative clause:
|
|
8
8
|
|
|
9
|
-
-
|
|
9
|
+
- put the exact clause as `claim_text` on its ground fact, with the returned stable key as `claim_key` or none (Kibi derives a missing key; a sent key must match);
|
|
10
10
|
- add the key to the exact current `logic_claims` set, removing only stale keys whose propositions no longer exist in the source;
|
|
11
11
|
- link it through exactly one `requires_property` for `property_value`, one `requires_predicate` for `predicate`, or one `requires_rule` for a safe `rule` fact;
|
|
12
12
|
- leave ambiguity and ontology gaps visibly unresolved—observations do not satisfy `logic-coverage`.
|
|
@@ -126,8 +126,8 @@ diagnostics (`symbol_semantic_review_needed`).
|
|
|
126
126
|
`requires_predicate`.
|
|
127
127
|
3. Scalar placement/alignment/order clauses: `kb_model` (`mode: "requirement"`), apply the strict
|
|
128
128
|
subject/property plan and `constrains` / `requires_property`.
|
|
129
|
-
4. Preserve `claim_key` / `claim_text
|
|
130
|
-
`logic_claims` manifest.
|
|
129
|
+
4. Preserve `claim_key` / `claim_text` (a missing key is derived from the
|
|
130
|
+
text); merge every key into the requirement `logic_claims` manifest.
|
|
131
131
|
5. `kb_upsert` with `dryRun: true`, create endpoints first, then sequential `kb_upsert`.
|
|
132
132
|
6. `kb_check` with `logic-coverage`, `predicate-verifiability`, `domain-contradictions`,
|
|
133
133
|
then a final unfiltered `kb_check`.
|
|
@@ -203,7 +203,7 @@ Optional per-project workflow for recording what the screen should look like. No
|
|
|
203
203
|
2. Run `kb_model` with `mode: "analyze"` on the description; audit or supply `clauses`.
|
|
204
204
|
3. For relational layout clauses ("X must remain visually aligned with Y"), call `kb_model` with `mode: "predicates"`, apply the returned `fact_kind: predicate` plan with `predicate_name: visual_layout_rule` and `requires_predicate`.
|
|
205
205
|
4. For scalar placement, alignment, and ordering clauses, call `kb_model` with `mode: "requirement"` and apply strict `fact_kind: subject` / `fact_kind: property_value` facts linked with `constrains` / `requires_property`. Model header order as indexed property keys (`nav_order_1`, `nav_order_2`, ...) against one subject region.
|
|
206
|
-
5. Preserve `claim_key` / `claim_text` on every ground fact and merge every key into the requirement `logic_claims` manifest.
|
|
206
|
+
5. Preserve `claim_key` / `claim_text` on every ground fact (a missing `claim_key` is derived from `claim_text`) and merge every key into the requirement `logic_claims` manifest.
|
|
207
207
|
6. Model UI components as `symbol` entities with `sourceFile` and `symbol_role: behavioral`, linked `implements` to the requirement.
|
|
208
208
|
7. `kb_upsert` with `dryRun: true`, create endpoints first, then sequential `kb_upsert`. Run `kb_check` with `logic-coverage`, `predicate-verifiability`, and `domain-contradictions`, then a final unfiltered `kb_check`.
|
|
209
209
|
|
|
@@ -1675,35 +1675,12 @@
|
|
|
1675
1675
|
},
|
|
1676
1676
|
{
|
|
1677
1677
|
"if": {
|
|
1678
|
-
"
|
|
1679
|
-
|
|
1680
|
-
"required": [
|
|
1681
|
-
"claim_key"
|
|
1682
|
-
]
|
|
1683
|
-
},
|
|
1684
|
-
{
|
|
1685
|
-
"required": [
|
|
1686
|
-
"claim_text"
|
|
1687
|
-
],
|
|
1688
|
-
"not": {
|
|
1689
|
-
"properties": {
|
|
1690
|
-
"fact_kind": {
|
|
1691
|
-
"enum": [
|
|
1692
|
-
"observation",
|
|
1693
|
-
"meta"
|
|
1694
|
-
]
|
|
1695
|
-
}
|
|
1696
|
-
},
|
|
1697
|
-
"required": [
|
|
1698
|
-
"fact_kind"
|
|
1699
|
-
]
|
|
1700
|
-
}
|
|
1701
|
-
}
|
|
1678
|
+
"required": [
|
|
1679
|
+
"claim_key"
|
|
1702
1680
|
]
|
|
1703
1681
|
},
|
|
1704
1682
|
"then": {
|
|
1705
1683
|
"required": [
|
|
1706
|
-
"claim_key",
|
|
1707
1684
|
"claim_text"
|
|
1708
1685
|
]
|
|
1709
1686
|
}
|