kibi-cli 2.26.1 → 2.26.3

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.
Files changed (41) hide show
  1. package/dist/commands/migrate.d.ts.map +1 -1
  2. package/dist/commands/migrate.js +10 -2
  3. package/dist/commands/sync/cache.d.ts +21 -0
  4. package/dist/commands/sync/cache.d.ts.map +1 -1
  5. package/dist/commands/sync/cache.js +40 -15
  6. package/dist/commands/sync.d.ts.map +1 -1
  7. package/dist/commands/sync.js +21 -10
  8. package/dist/intent-search.d.ts.map +1 -1
  9. package/dist/intent-search.js +14 -3
  10. package/dist/operations/mutation/requirement-semantics.d.ts +5 -0
  11. package/dist/operations/mutation/requirement-semantics.d.ts.map +1 -1
  12. package/dist/operations/mutation/requirement-semantics.js +24 -5
  13. package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
  14. package/dist/operations/mutation/source-authoring.js +30 -2
  15. package/dist/operations/mutation/stored-entity.d.ts +7 -0
  16. package/dist/operations/mutation/stored-entity.d.ts.map +1 -1
  17. package/dist/operations/mutation/types.d.ts +1 -1
  18. package/dist/operations/mutation/types.d.ts.map +1 -1
  19. package/dist/operations/mutation/uncompiled-source.d.ts +6 -0
  20. package/dist/operations/mutation/uncompiled-source.d.ts.map +1 -1
  21. package/dist/operations/mutation/uncompiled-source.js +17 -1
  22. package/dist/operations/planning/apply-plan.d.ts.map +1 -1
  23. package/dist/operations/planning/apply-plan.js +4 -2
  24. package/dist/prolog/utf8-transport.d.ts +21 -0
  25. package/dist/prolog/utf8-transport.d.ts.map +1 -0
  26. package/dist/prolog/utf8-transport.js +49 -0
  27. package/dist/prolog.d.ts +2 -0
  28. package/dist/prolog.d.ts.map +1 -1
  29. package/dist/prolog.js +19 -10
  30. package/dist/public/operations/catalog.d.ts +1 -1
  31. package/dist/public/operations/migration-plan.d.ts +25 -0
  32. package/dist/public/operations/migration-plan.d.ts.map +1 -1
  33. package/dist/public/operations/migration-plan.js +40 -0
  34. package/dist/public/operations/specs/upsert.d.ts +1 -1
  35. package/dist/public/operations/specs/upsert.js +1 -1
  36. package/dist/search-answer.d.ts +9 -0
  37. package/dist/search-answer.d.ts.map +1 -1
  38. package/dist/search-answer.js +66 -3
  39. package/package.json +1 -1
  40. package/src/public/operations/migration-plan.ts +72 -0
  41. package/src/public/operations/specs/upsert.ts +1 -1
@@ -2210,7 +2210,7 @@ async function applyMigrationPlan(args, context, onCommitted = () => undefined)
2210
2210
  const operationContext = context.prolog
2211
2211
  ? context
2212
2212
  : { ...context, prolog };
2213
- const [{ executeCheck }, { executeCoverage }, { mergeMigrationPlans }] = await Promise.all([
2213
+ const [{ executeCheck }, { executeCoverage }, { digestMigrationPlan, mergeMigrationPlans },] = await Promise.all([
2214
2214
  import("../../public/operations/check-executor.js"),
2215
2215
  import("../../public/operations/specs/reporting.js"),
2216
2216
  import("../../public/operations/migration-plan.js"),
@@ -2223,8 +2223,10 @@ async function applyMigrationPlan(args, context, onCommitted = () => undefined)
2223
2223
  coverage.structuredContent?.migrationPlan,
2224
2224
  symbolCoverage.structuredContent?.migrationPlan,
2225
2225
  ].filter((value) => value !== undefined);
2226
+ // The response reports what is left; the full plan, with every
2227
+ // review and execution action, stays with status, check and coverage.
2226
2228
  if (fragments.length > 0)
2227
- remainingPlan = mergeMigrationPlans(fragments);
2229
+ remainingPlan = digestMigrationPlan(mergeMigrationPlans(fragments));
2228
2230
  coverageSummary = coverage.structuredContent?.summary;
2229
2231
  }
2230
2232
  }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Prolog goal that switches the child's standard streams and its default
3
+ * file encoding to UTF-8. SWI-Prolog otherwise follows the process locale,
4
+ * and under a POSIX locale every non-ASCII byte read from stdin becomes
5
+ * U+FFFD, which the store then persists.
6
+ */
7
+ export declare const PROLOG_UTF8_STREAMS_GOAL = "set_prolog_flag(encoding, utf8), set_stream(user_input, encoding(utf8)), set_stream(user_output, encoding(utf8)), set_stream(user_error, encoding(utf8))";
8
+ /**
9
+ * Encode a goal for an environment variable. SWI-Prolog decodes environment
10
+ * values with the process locale, so non-ASCII goal text travels as base64
11
+ * of its UTF-8 bytes.
12
+ */
13
+ export declare function encodeGoalForEnv(goal: string): string;
14
+ /** Prolog goal that binds `Atom` to the goal stored by `encodeGoalForEnv`. */
15
+ export declare function decodeGoalFromEnvGoal(variable: string, atom: string): string;
16
+ /**
17
+ * A UTF-8 decoder for one child stream that keeps a character split across
18
+ * two chunks whole instead of decoding each half to U+FFFD.
19
+ */
20
+ export declare function utf8ChunkDecoder(): (chunk: Buffer) => string;
21
+ //# sourceMappingURL=utf8-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utf8-transport.d.ts","sourceRoot":"","sources":["../../src/prolog/utf8-transport.ts"],"names":[],"mappings":"AAqBA;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,6JACuH,CAAC;AAG7J;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAGD,8EAA8E;AAC9E,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5E;AAGD;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAG5D"}
@@ -0,0 +1,49 @@
1
+ /*
2
+ Kibi — repo-local, per-branch, queryable long-term memory for software projects
3
+ Copyright (C) 2026 Piotr Franczyk
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU Affero General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU Affero General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Affero General Public License
16
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+ */
18
+ import { StringDecoder } from "node:string_decoder";
19
+ // implements REQ-prolog-utf8-text
20
+ /**
21
+ * Prolog goal that switches the child's standard streams and its default
22
+ * file encoding to UTF-8. SWI-Prolog otherwise follows the process locale,
23
+ * and under a POSIX locale every non-ASCII byte read from stdin becomes
24
+ * U+FFFD, which the store then persists.
25
+ */
26
+ export const PROLOG_UTF8_STREAMS_GOAL = "set_prolog_flag(encoding, utf8), set_stream(user_input, encoding(utf8)), set_stream(user_output, encoding(utf8)), set_stream(user_error, encoding(utf8))";
27
+ // implements REQ-prolog-utf8-text
28
+ /**
29
+ * Encode a goal for an environment variable. SWI-Prolog decodes environment
30
+ * values with the process locale, so non-ASCII goal text travels as base64
31
+ * of its UTF-8 bytes.
32
+ */
33
+ export function encodeGoalForEnv(goal) {
34
+ return Buffer.from(goal, "utf8").toString("base64");
35
+ }
36
+ // implements REQ-prolog-utf8-text
37
+ /** Prolog goal that binds `Atom` to the goal stored by `encodeGoalForEnv`. */
38
+ export function decodeGoalFromEnvGoal(variable, atom) {
39
+ return `getenv('${variable}', ${atom}Encoded), base64_encoded(${atom}, ${atom}Encoded, [encoding(utf8), as(atom)])`;
40
+ }
41
+ // implements REQ-prolog-utf8-text
42
+ /**
43
+ * A UTF-8 decoder for one child stream that keeps a character split across
44
+ * two chunks whole instead of decoding each half to U+FFFD.
45
+ */
46
+ export function utf8ChunkDecoder() {
47
+ const decoder = new StringDecoder("utf8");
48
+ return (chunk) => decoder.write(chunk);
49
+ }
package/dist/prolog.d.ts CHANGED
@@ -52,6 +52,8 @@ export declare class PrologProcess {
52
52
  private outputOverflowed;
53
53
  private errorBuffer;
54
54
  private errorBufferBytes;
55
+ private decodeOutput;
56
+ private decodeError;
55
57
  private cache;
56
58
  private interactiveQueryTail;
57
59
  private terminationPromise;
@@ -1 +1 @@
1
- {"version":3,"file":"prolog.d.ts","sourceRoot":"","sources":["../src/prolog.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prolog.d.ts","sourceRoot":"","sources":["../src/prolog.ts"],"names":[],"mappings":"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"}
package/dist/prolog.js CHANGED
@@ -26,6 +26,7 @@ import { kibiPackageVersions } from "./package-versions.js";
26
26
  import { writePerformanceTraceEvent } from "./performance-trace.js";
27
27
  import { extractPrologErrorRecord, } from "./prolog/error-terms.js";
28
28
  import { resolveSwipl, swiplChildEnv, } from "./prolog/swipl-resolver.js";
29
+ import { PROLOG_UTF8_STREAMS_GOAL, decodeGoalFromEnvGoal, encodeGoalForEnv, utf8ChunkDecoder, } from "./prolog/utf8-transport.js";
29
30
  const importMetaDir = path.dirname(fileURLToPath(import.meta.url));
30
31
  const DEFAULT_PROLOG_OUTPUT_MAX_BUFFER_BYTES = 8 * 1024 * 1024;
31
32
  const PROLOG_OUTPUT_OVERFLOW_ERROR = "Query exceeded bounded Prolog output capacity (ENOBUFS); narrow the operation or reduce stored entity size";
@@ -106,6 +107,8 @@ export class PrologProcess {
106
107
  outputOverflowed = false;
107
108
  errorBuffer = "";
108
109
  errorBufferBytes = 0;
110
+ decodeOutput = utf8ChunkDecoder();
111
+ decodeError = utf8ChunkDecoder();
109
112
  cache = new Map();
110
113
  interactiveQueryTail = Promise.resolve();
111
114
  terminationPromise = null;
@@ -183,7 +186,7 @@ export class PrologProcess {
183
186
  this.invalidateCache();
184
187
  this.process = spawn(launch.bin, [
185
188
  "-g",
186
- `use_module('${kbPath}'), use_module(library(semweb/rdf_db)), set_prolog_flag(answer_write_options, [max_depth(0), quoted(true)])`,
189
+ `${PROLOG_UTF8_STREAMS_GOAL}, use_module('${kbPath}'), use_module(library(semweb/rdf_db)), set_prolog_flag(answer_write_options, [max_depth(0), quoted(true)])`,
187
190
  "--quiet",
188
191
  ], {
189
192
  detached: process.platform !== "win32",
@@ -196,6 +199,8 @@ export class PrologProcess {
196
199
  },
197
200
  });
198
201
  this.clearQueryBuffers();
202
+ this.decodeOutput = utf8ChunkDecoder();
203
+ this.decodeError = utf8ChunkDecoder();
199
204
  if (!this.process.stdout || !this.process.stderr || !this.process.stdin) {
200
205
  throw new Error("Failed to spawn Prolog process");
201
206
  }
@@ -574,10 +579,11 @@ export class PrologProcess {
574
579
  : `(${goalList.join(", ")})`;
575
580
  const kbModulePath = resolveKbPlPath();
576
581
  const prologGoal = [
582
+ PROLOG_UTF8_STREAMS_GOAL,
577
583
  `use_module('${kbModulePath}')`,
578
584
  "use_module(library(semweb/rdf_db))",
579
585
  "set_prolog_flag(answer_write_options, [max_depth(0), quoted(true)])",
580
- "getenv('KIBI_GOAL', GoalAtom)",
586
+ decodeGoalFromEnvGoal("KIBI_GOAL", "GoalAtom"),
581
587
  "read_term_from_atom(GoalAtom, Goal, [variable_names(Vars)])",
582
588
  kbPath ? "getenv('KIBI_KB_PATH', KBPath), kb_attach(KBPath)" : "true",
583
589
  isBatch ? "WrappedGoal = rdf_transaction(Goal)" : "WrappedGoal = Goal",
@@ -601,7 +607,7 @@ export class PrologProcess {
601
607
  env: {
602
608
  ...process.env,
603
609
  ...launch.env,
604
- KIBI_GOAL: combinedGoal,
610
+ KIBI_GOAL: encodeGoalForEnv(combinedGoal ?? "true"),
605
611
  KIBI_RUNTIME_NAME: runtimeName,
606
612
  KIBI_RUNTIME_VERSION: runtimeVersion,
607
613
  KIBI_PACKAGE_VERSIONS: packageVersions,
@@ -627,13 +633,16 @@ export class PrologProcess {
627
633
  let settled = false;
628
634
  let closed = false;
629
635
  let termination = null;
636
+ const decodeStdout = utf8ChunkDecoder();
637
+ const decodeStderr = utf8ChunkDecoder();
630
638
  const appendChunk = (chunk, target) => {
631
639
  if (outputOverflowed)
632
640
  return;
633
641
  const bytes = target === "stdout" ? outputBytes : errorBytes;
634
642
  const remaining = this.maxOutputBytes - bytes;
643
+ const decode = target === "stdout" ? decodeStdout : decodeStderr;
635
644
  if (chunk.byteLength > remaining) {
636
- const clipped = chunk.subarray(0, Math.max(0, remaining)).toString();
645
+ const clipped = decode(chunk.subarray(0, Math.max(0, remaining)));
637
646
  if (target === "stdout")
638
647
  stdout += clipped;
639
648
  else
@@ -643,11 +652,11 @@ export class PrologProcess {
643
652
  return;
644
653
  }
645
654
  if (target === "stdout") {
646
- stdout += chunk.toString();
655
+ stdout += decode(chunk);
647
656
  outputBytes += chunk.byteLength;
648
657
  }
649
658
  else {
650
- stderr += chunk.toString();
659
+ stderr += decode(chunk);
651
660
  errorBytes += chunk.byteLength;
652
661
  }
653
662
  };
@@ -749,12 +758,12 @@ export class PrologProcess {
749
758
  return;
750
759
  const remaining = this.maxOutputBytes - this.outputBufferBytes;
751
760
  if (chunk.byteLength > remaining) {
752
- this.outputBuffer += chunk.subarray(0, remaining).toString();
761
+ this.outputBuffer += this.decodeOutput(chunk.subarray(0, remaining));
753
762
  this.outputBufferBytes = this.maxOutputBytes;
754
763
  this.outputOverflowed = true;
755
764
  return;
756
765
  }
757
- this.outputBuffer += chunk.toString();
766
+ this.outputBuffer += this.decodeOutput(chunk);
758
767
  this.outputBufferBytes += chunk.byteLength;
759
768
  this.wakeOutputWaiter();
760
769
  }
@@ -763,12 +772,12 @@ export class PrologProcess {
763
772
  return;
764
773
  const remaining = this.maxOutputBytes - this.errorBufferBytes;
765
774
  if (chunk.byteLength > remaining) {
766
- this.errorBuffer += chunk.subarray(0, remaining).toString();
775
+ this.errorBuffer += this.decodeError(chunk.subarray(0, remaining));
767
776
  this.errorBufferBytes = this.maxOutputBytes;
768
777
  this.outputOverflowed = true;
769
778
  return;
770
779
  }
771
- this.errorBuffer += chunk.toString();
780
+ this.errorBuffer += this.decodeError(chunk);
772
781
  this.errorBufferBytes += chunk.byteLength;
773
782
  this.wakeOutputWaiter();
774
783
  }
@@ -1746,7 +1746,7 @@ export declare const OPERATION_CATALOG: readonly [{
1746
1746
  readonly document: {
1747
1747
  readonly type: "object";
1748
1748
  readonly additionalProperties: false;
1749
- readonly description: "Optional source-first document write. Paths are workspace-relative; omit body when updating to preserve the existing body bytes. For a new requirement pass a sectioned body: statement, '## Context' (why, who asked, constraints), '## Source' (blockquoted excerpt and reference); context never changes the checked meaning, which stays in semantic_text.";
1749
+ readonly description: "Optional source-first document write. Paths are workspace-relative; omit body when updating to preserve the existing body bytes (a requirement whose semantic_text changes gets the new statement in place of the old one, with its context sections kept). For a new requirement pass a sectioned body: statement, '## Context' (why, who asked, constraints), '## Source' (blockquoted excerpt and reference); context never changes the checked meaning, which stays in semantic_text.";
1750
1750
  readonly properties: {
1751
1751
  readonly path: {
1752
1752
  readonly type: "string";
@@ -69,6 +69,31 @@ export declare function migrationPlanHash(value: unknown): string;
69
69
  export declare function compareReadyActionIds(left: string, right: string, byId: ReadonlyMap<string, MigrationAction>): number;
70
70
  export declare function buildMigrationPlan(input?: PlanInput): MigrationPlan;
71
71
  export declare function mergeMigrationPlans(plans: readonly MigrationPlan[]): MigrationPlan;
72
+ export declare const MIGRATION_PLAN_DIGEST_VERSION: "kibi.migration-plan-digest.v1";
73
+ export type MigrationPlanDigest = Readonly<{
74
+ version: typeof MIGRATION_PLAN_DIGEST_VERSION;
75
+ planHash: string;
76
+ status: MigrationPlan["status"];
77
+ expected: MigrationPlan["expected"];
78
+ scope: MigrationPlan["scope"];
79
+ summary: MigrationPlan["summary"];
80
+ automaticActions: readonly MigrationAction[];
81
+ actionGroups: readonly Readonly<{
82
+ code: string;
83
+ safety: MigrationSafety;
84
+ state: MigrationActionState;
85
+ count: number;
86
+ }>[];
87
+ diagnostics: readonly string[];
88
+ next: string;
89
+ }>;
90
+ /**
91
+ * A bounded summary of a plan for responses that report what is left rather
92
+ * than hand over a plan to apply: automatic actions stay whole, every other
93
+ * action is counted by code. The full plan comes from status, check and
94
+ * coverage.
95
+ */
96
+ export declare function digestMigrationPlan(plan: MigrationPlan): MigrationPlanDigest;
72
97
  /**
73
98
  * The same plan without the actions whose code another planner owns, e.g.
74
99
  * lifecycle repairs `kibi migrate` plans from authored sources.
@@ -1 +1 @@
1
- {"version":3,"file":"migration-plan.d.ts","sourceRoot":"","sources":["../../../src/public/operations/migration-plan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"migration-plan.d.ts","sourceRoot":"","sources":["../../../src/public/operations/migration-plan.ts"],"names":[],"mappings":"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"}
@@ -172,6 +172,46 @@ export function mergeMigrationPlans(plans) {
172
172
  diagnostics: [...diagnostics],
173
173
  });
174
174
  }
175
+ export const MIGRATION_PLAN_DIGEST_VERSION = "kibi.migration-plan-digest.v1";
176
+ /**
177
+ * A bounded summary of a plan for responses that report what is left rather
178
+ * than hand over a plan to apply: automatic actions stay whole, every other
179
+ * action is counted by code. The full plan comes from status, check and
180
+ * coverage.
181
+ */
182
+ // implements REQ-agent-guided-migration-orchestration
183
+ export function digestMigrationPlan(plan) {
184
+ const groups = new Map();
185
+ for (const action of plan.actions) {
186
+ if (action.safety === "automatic")
187
+ continue;
188
+ const key = `${action.code}\u0000${action.safety}\u0000${action.state}`;
189
+ const group = groups.get(key);
190
+ if (group === undefined)
191
+ groups.set(key, {
192
+ code: action.code,
193
+ safety: action.safety,
194
+ state: action.state,
195
+ count: 1,
196
+ });
197
+ else
198
+ group.count += 1;
199
+ }
200
+ return {
201
+ version: MIGRATION_PLAN_DIGEST_VERSION,
202
+ planHash: plan.planHash,
203
+ status: plan.status,
204
+ expected: plan.expected,
205
+ scope: plan.scope,
206
+ summary: plan.summary,
207
+ automaticActions: plan.actions.filter((action) => action.safety === "automatic"),
208
+ actionGroups: [...groups.values()].sort((left, right) => right.count - left.count ||
209
+ left.code.localeCompare(right.code) ||
210
+ left.state.localeCompare(right.state)),
211
+ diagnostics: plan.diagnostics,
212
+ next: "This digest cannot be applied. Run kb_status, kb_check and kb_coverage (or kibi migrate) for the full plan and its action details.",
213
+ };
214
+ }
175
215
  /**
176
216
  * The same plan without the actions whose code another planner owns, e.g.
177
217
  * lifecycle repairs `kibi migrate` plans from authored sources.
@@ -759,7 +759,7 @@ export declare const upsertSpec: {
759
759
  readonly document: {
760
760
  readonly type: "object";
761
761
  readonly additionalProperties: false;
762
- readonly description: "Optional source-first document write. Paths are workspace-relative; omit body when updating to preserve the existing body bytes. For a new requirement pass a sectioned body: statement, '## Context' (why, who asked, constraints), '## Source' (blockquoted excerpt and reference); context never changes the checked meaning, which stays in semantic_text.";
762
+ readonly description: "Optional source-first document write. Paths are workspace-relative; omit body when updating to preserve the existing body bytes (a requirement whose semantic_text changes gets the new statement in place of the old one, with its context sections kept). For a new requirement pass a sectioned body: statement, '## Context' (why, who asked, constraints), '## Source' (blockquoted excerpt and reference); context never changes the checked meaning, which stays in semantic_text.";
763
763
  readonly properties: {
764
764
  readonly path: {
765
765
  readonly type: "string";
@@ -41,7 +41,7 @@ export const upsertSpec = {
41
41
  document: {
42
42
  type: "object",
43
43
  additionalProperties: false,
44
- description: "Optional source-first document write. Paths are workspace-relative; omit body when updating to preserve the existing body bytes. For a new requirement pass a sectioned body: statement, '## Context' (why, who asked, constraints), '## Source' (blockquoted excerpt and reference); context never changes the checked meaning, which stays in semantic_text.",
44
+ description: "Optional source-first document write. Paths are workspace-relative; omit body when updating to preserve the existing body bytes (a requirement whose semantic_text changes gets the new statement in place of the old one, with its context sections kept). For a new requirement pass a sectioned body: statement, '## Context' (why, who asked, constraints), '## Source' (blockquoted excerpt and reference); context never changes the checked meaning, which stays in semantic_text.",
45
45
  properties: {
46
46
  path: { type: "string", minLength: 1 },
47
47
  body: { type: "string" },
@@ -124,6 +124,15 @@ export type SearchAnswerScope = Readonly<{
124
124
  export type SearchAnswerUngoverned = SearchAnswerFact & Readonly<{
125
125
  type: string;
126
126
  rank: number;
127
+ /**
128
+ * The governing requirement's fact on the same predicate and key
129
+ * arguments that this unlinked fact disagrees with; that fact holds.
130
+ */
131
+ overriddenBy?: Readonly<{
132
+ fact: string;
133
+ requirement: string;
134
+ claim?: string;
135
+ }>;
127
136
  }>;
128
137
  export type SearchAnswer = Readonly<{
129
138
  version: "kibi.search-answer.v1";
@@ -1 +1 @@
1
- {"version":3,"file":"search-answer.d.ts","sourceRoot":"","sources":["../src/search-answer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"search-answer.d.ts","sourceRoot":"","sources":["../src/search-answer.ts"],"names":[],"mappings":"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"}
@@ -128,6 +128,38 @@ export function predicateKeyFilter(args, schema) {
128
128
  }
129
129
  return Object.keys(where).length > 0 ? where : undefined;
130
130
  }
131
+ /**
132
+ * Whether two predicate facts state the same predicate, namespace and key
133
+ * arguments with other values or polarity. Without declared key arguments
134
+ * two tuples may both hold (alice has two roles), so no pair is claimed.
135
+ */
136
+ // implements REQ-search-answer-hygiene
137
+ function disagreeingPredicateFacts(left, right, schema) {
138
+ if (schema === undefined ||
139
+ !schema.keyArguments.some((key) => schema.argumentNames.includes(key)))
140
+ return false;
141
+ if (text(left.fact_kind) !== "predicate")
142
+ return false;
143
+ if (text(right.fact_kind) !== "predicate")
144
+ return false;
145
+ if (text(left.predicate_name) !== text(right.predicate_name))
146
+ return false;
147
+ const namespace = (row) => text(row.predicate_namespace) || "default";
148
+ if (namespace(left) !== namespace(right))
149
+ return false;
150
+ const argsOf = (row) => Array.isArray(row.predicate_args) ? row.predicate_args.map(text) : [];
151
+ const leftArgs = argsOf(left);
152
+ const rightArgs = argsOf(right);
153
+ const leftKey = predicateKeyFilter(leftArgs, schema);
154
+ const rightKey = predicateKeyFilter(rightArgs, schema);
155
+ if (leftKey === undefined || rightKey === undefined)
156
+ return false;
157
+ if (JSON.stringify(leftKey) !== JSON.stringify(rightKey))
158
+ return false;
159
+ const deny = (row) => text(row.polarity) === "deny";
160
+ return (deny(left) !== deny(right) ||
161
+ leftArgs.some((value, index) => value !== rightArgs[index]));
162
+ }
131
163
  /** Typed statement and follow-up query of a linked fact, by fact kind. */
132
164
  // implements REQ-kibi-query-fact-filters
133
165
  function factDetail(fact, schema) {
@@ -885,17 +917,40 @@ export async function buildSearchAnswer(prolog, matches, options = {}) {
885
917
  ? verdicts.scope.syncedAt
886
918
  : null,
887
919
  };
888
- detailedUngoverned.sort((left, right) => left.rank - right.rank);
920
+ // An unlinked predicate fact that disagrees with a governing requirement's
921
+ // fact on the same key arguments names that fact, so the answer says which
922
+ // one decides instead of leaving the agent to find the pair.
923
+ const governingFacts = plans.flatMap((plan) => rowsOf(plan.facts).map((fact) => ({ fact, requirement: plan.req.id })));
924
+ const ungovernedAnswer = detailedUngoverned
925
+ .map((entry) => {
926
+ const row = entry.type === "fact" ? graph.row(entry.id) : null;
927
+ if (row === null)
928
+ return entry;
929
+ const holder = governingFacts.find(({ fact }) => disagreeingPredicateFacts(row, fact, schemas.get(entry.id)));
930
+ if (holder === undefined)
931
+ return entry;
932
+ const factId = text(holder.fact.id);
933
+ const { claim } = factDetail(holder.fact, schemas.get(factId));
934
+ return {
935
+ ...entry,
936
+ overriddenBy: {
937
+ fact: factId,
938
+ requirement: holder.requirement,
939
+ ...(claim ? { claim } : {}),
940
+ },
941
+ };
942
+ })
943
+ .sort((left, right) => left.rank - right.rank);
889
944
  const answer = {
890
945
  version: "kibi.search-answer.v1",
891
946
  governing,
892
947
  rationale,
893
948
  notGoverning,
894
949
  observations: observations.slice(0, limits.observations),
895
- ungoverned: detailedUngoverned,
950
+ ungoverned: ungovernedAnswer,
896
951
  scope,
897
952
  truncated: truncated || graph.truncated,
898
- note: answerNote(governing.length, detailedUngoverned),
953
+ note: answerNote(governing.length, ungovernedAnswer),
899
954
  };
900
955
  return fitSearchAnswer(answer, limits.maxBytes);
901
956
  }
@@ -916,8 +971,16 @@ function answerNote(governingCount, ungoverned) {
916
971
  const ungovernedFact = ungoverned.some((entry) => entry.type === "fact")
917
972
  ? "A fact in ungoverned is linked to no requirement, so it decides nothing: where it disagrees with a governing requirement's fact, the governing fact holds. "
918
973
  : "";
974
+ const overridden = ungoverned
975
+ .flatMap((entry) => entry.overriddenBy === undefined
976
+ ? []
977
+ : [
978
+ `${entry.overriddenBy.fact} of ${entry.overriddenBy.requirement}${entry.overriddenBy.claim ? ` (${entry.overriddenBy.claim})` : ""} holds over ${entry.id}${entry.claim ? ` (${entry.claim})` : ""}. `,
979
+ ])
980
+ .join("");
919
981
  return (lead +
920
982
  ungovernedFact +
983
+ overridden +
921
984
  (governingCount === 0
922
985
  ? "No current requirement matched or owns a matched entity. Absence here is not evidence that nothing governs the change; refine the query or pass sourceLocations."
923
986
  : "Governing requirements are current requirements matched by the query or linked to a matched entity. Links are discovery, not proof. A verdict lists the contradiction and scenario-feasibility witnesses that name the requirement; none means no check named it, not that it is proven. Use kb_check and kb_coverage for consistency and proof status."));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kibi-cli",
3
- "version": "2.26.1",
3
+ "version": "2.26.3",
4
4
  "type": "module",
5
5
  "description": "Kibi CLI for knowledge base management",
6
6
  "engines": {
@@ -293,6 +293,78 @@ export function mergeMigrationPlans(
293
293
  });
294
294
  }
295
295
 
296
+ export const MIGRATION_PLAN_DIGEST_VERSION =
297
+ "kibi.migration-plan-digest.v1" as const;
298
+
299
+ export type MigrationPlanDigest = Readonly<{
300
+ version: typeof MIGRATION_PLAN_DIGEST_VERSION;
301
+ planHash: string;
302
+ status: MigrationPlan["status"];
303
+ expected: MigrationPlan["expected"];
304
+ scope: MigrationPlan["scope"];
305
+ summary: MigrationPlan["summary"];
306
+ automaticActions: readonly MigrationAction[];
307
+ actionGroups: readonly Readonly<{
308
+ code: string;
309
+ safety: MigrationSafety;
310
+ state: MigrationActionState;
311
+ count: number;
312
+ }>[];
313
+ diagnostics: readonly string[];
314
+ next: string;
315
+ }>;
316
+
317
+ /**
318
+ * A bounded summary of a plan for responses that report what is left rather
319
+ * than hand over a plan to apply: automatic actions stay whole, every other
320
+ * action is counted by code. The full plan comes from status, check and
321
+ * coverage.
322
+ */
323
+ // implements REQ-agent-guided-migration-orchestration
324
+ export function digestMigrationPlan(plan: MigrationPlan): MigrationPlanDigest {
325
+ const groups = new Map<
326
+ string,
327
+ {
328
+ code: string;
329
+ safety: MigrationSafety;
330
+ state: MigrationActionState;
331
+ count: number;
332
+ }
333
+ >();
334
+ for (const action of plan.actions) {
335
+ if (action.safety === "automatic") continue;
336
+ const key = `${action.code}\u0000${action.safety}\u0000${action.state}`;
337
+ const group = groups.get(key);
338
+ if (group === undefined)
339
+ groups.set(key, {
340
+ code: action.code,
341
+ safety: action.safety,
342
+ state: action.state,
343
+ count: 1,
344
+ });
345
+ else group.count += 1;
346
+ }
347
+ return {
348
+ version: MIGRATION_PLAN_DIGEST_VERSION,
349
+ planHash: plan.planHash,
350
+ status: plan.status,
351
+ expected: plan.expected,
352
+ scope: plan.scope,
353
+ summary: plan.summary,
354
+ automaticActions: plan.actions.filter(
355
+ (action) => action.safety === "automatic",
356
+ ),
357
+ actionGroups: [...groups.values()].sort(
358
+ (left, right) =>
359
+ right.count - left.count ||
360
+ left.code.localeCompare(right.code) ||
361
+ left.state.localeCompare(right.state),
362
+ ),
363
+ diagnostics: plan.diagnostics,
364
+ next: "This digest cannot be applied. Run kb_status, kb_check and kb_coverage (or kibi migrate) for the full plan and its action details.",
365
+ };
366
+ }
367
+
296
368
  /**
297
369
  * The same plan without the actions whose code another planner owns, e.g.
298
370
  * lifecycle repairs `kibi migrate` plans from authored sources.
@@ -57,7 +57,7 @@ export const upsertSpec = {
57
57
  type: "object",
58
58
  additionalProperties: false,
59
59
  description:
60
- "Optional source-first document write. Paths are workspace-relative; omit body when updating to preserve the existing body bytes. For a new requirement pass a sectioned body: statement, '## Context' (why, who asked, constraints), '## Source' (blockquoted excerpt and reference); context never changes the checked meaning, which stays in semantic_text.",
60
+ "Optional source-first document write. Paths are workspace-relative; omit body when updating to preserve the existing body bytes (a requirement whose semantic_text changes gets the new statement in place of the old one, with its context sections kept). For a new requirement pass a sectioned body: statement, '## Context' (why, who asked, constraints), '## Source' (blockquoted excerpt and reference); context never changes the checked meaning, which stays in semantic_text.",
61
61
  properties: {
62
62
  path: { type: "string", minLength: 1 },
63
63
  body: { type: "string" },