kibi-cli 2.28.0 → 2.29.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.
Files changed (48) hide show
  1. package/bin/kibi +12 -1
  2. package/dist/cli-command.d.ts +3 -0
  3. package/dist/cli-command.d.ts.map +1 -1
  4. package/dist/cli-command.js +11 -0
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +5 -2
  7. package/dist/commands/check.d.ts.map +1 -1
  8. package/dist/commands/check.js +4 -1
  9. package/dist/commands/engine.d.ts.map +1 -1
  10. package/dist/commands/engine.js +26 -2
  11. package/dist/commands/sync/manifest.d.ts.map +1 -1
  12. package/dist/commands/sync/manifest.js +6 -7
  13. package/dist/commands/sync.d.ts +10 -0
  14. package/dist/commands/sync.d.ts.map +1 -1
  15. package/dist/commands/sync.js +67 -3
  16. package/dist/engine.d.ts +11 -1
  17. package/dist/engine.d.ts.map +1 -1
  18. package/dist/engine.js +120 -34
  19. package/dist/extractors/manifest.d.ts.map +1 -1
  20. package/dist/extractors/manifest.js +3 -5
  21. package/dist/extractors/symbol-coordinates.d.ts.map +1 -1
  22. package/dist/extractors/symbol-coordinates.js +3 -5
  23. package/dist/extractors/symbols-coordinator.d.ts.map +1 -1
  24. package/dist/extractors/symbols-coordinator.js +3 -4
  25. package/dist/operations/mutation/symbol-granularity.d.ts.map +1 -1
  26. package/dist/operations/mutation/symbol-granularity.js +4 -4
  27. package/dist/operations/mutation/symbol-refresh.d.ts.map +1 -1
  28. package/dist/operations/mutation/symbol-refresh.js +4 -3
  29. package/dist/operations/mutation/validation.js +11 -0
  30. package/dist/plugins/approved-source-analyzers.generated.d.ts +6 -6
  31. package/dist/plugins/approved-source-analyzers.generated.js +6 -6
  32. package/dist/prolog/error-terms.d.ts.map +1 -1
  33. package/dist/prolog/error-terms.js +15 -9
  34. package/dist/prolog/store-lock.d.ts +11 -0
  35. package/dist/prolog/store-lock.d.ts.map +1 -1
  36. package/dist/prolog/store-lock.js +48 -1
  37. package/dist/traceability/commit-amend.d.ts +7 -0
  38. package/dist/traceability/commit-amend.d.ts.map +1 -0
  39. package/dist/traceability/commit-amend.js +85 -0
  40. package/dist/traceability/staged-inventory-drift.d.ts +12 -2
  41. package/dist/traceability/staged-inventory-drift.d.ts.map +1 -1
  42. package/dist/traceability/staged-inventory-drift.js +22 -5
  43. package/dist/utils/repo-relative-path.d.ts +7 -0
  44. package/dist/utils/repo-relative-path.d.ts.map +1 -1
  45. package/dist/utils/repo-relative-path.js +26 -0
  46. package/package.json +4 -4
  47. package/schema/entities.pl +2 -1
  48. package/schema/validation.pl +15 -0
package/dist/engine.js CHANGED
@@ -293,10 +293,22 @@ function parseFrames(buffer, onFrame) {
293
293
  }
294
294
  return buffer.subarray(cursor);
295
295
  }
296
+ /**
297
+ * The socket directory every Kibi process for one user must agree on. Linux
298
+ * hosts and agent harnesses often give their children a private TMPDIR, so
299
+ * following it there would hide an engine from the CLI, git hooks and other
300
+ * hosts that share its branch store (they then see only `store_locked`).
301
+ * Linux therefore uses /tmp unless KIBI_RUNTIME_DIR or XDG_RUNTIME_DIR names
302
+ * a directory. macOS keeps its per-user TMPDIR, which launchd sets for every
303
+ * process of the user.
304
+ */
305
+ function defaultRuntimeDirectory() {
306
+ return path.join(process.platform === "linux" ? "/tmp" : os.tmpdir(), "kibi-runtime");
307
+ }
296
308
  export function runtimeDirectory() {
297
309
  const configured = process.env.KIBI_RUNTIME_DIR ??
298
310
  process.env.XDG_RUNTIME_DIR ??
299
- path.join(os.tmpdir(), "kibi-runtime");
311
+ defaultRuntimeDirectory();
300
312
  // Windows named pipes have no Unix socket pathname budget. Preserve its
301
313
  // filesystem location policy for the associated pid files.
302
314
  if (process.platform === "win32") {
@@ -340,38 +352,62 @@ export function runtimeDirectory() {
340
352
  const maximumBytes = process.platform === "linux" ? 107 : 103;
341
353
  const socketName = `kibi-${"0".repeat(32)}.sock`;
342
354
  for (const candidate of candidates) {
355
+ const rejection = runtimeDirectoryRejection(candidate, euid, socketName, maximumBytes);
356
+ if (typeof rejection === "object")
357
+ return rejection.directory;
358
+ if (candidate === process.env.KIBI_RUNTIME_DIR)
359
+ warnRuntimeDirectoryIgnored(candidate, rejection);
360
+ }
361
+ throw new Error("Unable to create a writable Kibi engine runtime directory");
362
+ }
363
+ /**
364
+ * The canonical runtime directory when `candidate` can hold the engine socket,
365
+ * else why it cannot.
366
+ */
367
+ function runtimeDirectoryRejection(candidate, euid, socketName, maximumBytes) {
368
+ try {
343
369
  try {
344
- try {
345
- if (lstatSync(candidate).isSymbolicLink())
346
- continue;
347
- }
348
- catch (error) {
349
- if (error.code !== "ENOENT")
350
- throw error;
351
- }
352
- mkdirSync(candidate, { recursive: true, mode: 0o700 });
353
- const directory = lstatSync(candidate);
354
- if (!directory.isDirectory() ||
355
- directory.uid !== euid ||
356
- (directory.mode & 0o077) !== 0)
357
- continue;
358
- const canonical = canonicalFilesystemPath(candidate);
359
- if (Buffer.byteLength(path.join(canonical, socketName), "utf8") >
360
- maximumBytes)
361
- continue;
362
- // XDG_RUNTIME_DIR can exist but be mounted read-only (for example in a
363
- // constrained container). Probe the directory before using it for the
364
- // socket, start lock, and pid files so auto-start fails over cleanly.
365
- const probe = path.join(canonical, `.kibi-write-${randomUUID()}`);
366
- writeFileSync(probe, "", { mode: 0o600, flag: "wx" });
367
- unlinkSync(probe);
368
- return canonical;
369
- }
370
- catch {
371
- // Try the private system-temp fallback below.
370
+ if (lstatSync(candidate).isSymbolicLink())
371
+ return "it is a symbolic link";
372
372
  }
373
+ catch (error) {
374
+ if (error.code !== "ENOENT")
375
+ throw error;
376
+ }
377
+ mkdirSync(candidate, { recursive: true, mode: 0o700 });
378
+ const directory = lstatSync(candidate);
379
+ if (!directory.isDirectory())
380
+ return "it is not a directory";
381
+ if (directory.uid !== euid)
382
+ return `it is owned by uid ${directory.uid}, not by the current user (uid ${euid})`;
383
+ if ((directory.mode & 0o077) !== 0)
384
+ return `its mode is ${(directory.mode & 0o777).toString(8).padStart(4, "0")}; it must be private to its owner (chmod 700)`;
385
+ const canonical = canonicalFilesystemPath(candidate);
386
+ if (Buffer.byteLength(path.join(canonical, socketName), "utf8") > maximumBytes)
387
+ return `its path is too long for a Unix socket (at most ${maximumBytes - socketName.length - 1} bytes)`;
388
+ // XDG_RUNTIME_DIR can exist but be mounted read-only (for example in a
389
+ // constrained container). Probe the directory before using it for the
390
+ // socket, start lock, and pid files so auto-start fails over cleanly.
391
+ const probe = path.join(canonical, `.kibi-write-${randomUUID()}`);
392
+ writeFileSync(probe, "", { mode: 0o600, flag: "wx" });
393
+ unlinkSync(probe);
394
+ return { directory: canonical };
395
+ }
396
+ catch (error) {
397
+ return `it is not usable (${error.message})`;
373
398
  }
374
- throw new Error("Unable to create a writable Kibi engine runtime directory");
399
+ }
400
+ const warnedRuntimeDirectories = new Set();
401
+ /**
402
+ * Processes that disagree on the runtime directory cannot reach each other's
403
+ * engine, so an explicit KIBI_RUNTIME_DIR that Kibi cannot use is reported
404
+ * (once per process) instead of being replaced silently.
405
+ */
406
+ function warnRuntimeDirectoryIgnored(directory, reason) {
407
+ if (warnedRuntimeDirectories.has(directory))
408
+ return;
409
+ warnedRuntimeDirectories.add(directory);
410
+ process.stderr.write(`kibi: ignoring KIBI_RUNTIME_DIR=${directory} because ${reason}; using a private directory under /tmp instead.\n`);
375
411
  }
376
412
  function fsyncPath(filePath) {
377
413
  if (!existsSync(filePath))
@@ -669,6 +705,18 @@ function recoverStaleJournalLock(branchPath) {
669
705
  // race between the liveness probe and removal.
670
706
  }
671
707
  }
708
+ /**
709
+ * The Node binary that hosts the daemon. A Node client starts it with its own
710
+ * runtime, so a host that runs Kibi through Node 22+ by absolute path still
711
+ * gets a Node 22+ daemon when an older `node` comes first on PATH. Bun clients
712
+ * (source checkouts, tests) use `node` from PATH, since the daemon is a Node
713
+ * artifact. KIBI_NODE_PATH overrides both.
714
+ */
715
+ export function daemonNodePath(environment = process.env) {
716
+ if (environment.KIBI_NODE_PATH)
717
+ return environment.KIBI_NODE_PATH;
718
+ return "Bun" in globalThis ? "node" : process.execPath;
719
+ }
672
720
  function daemonEntry() {
673
721
  const moduleDirectory = path.dirname(fileURLToPath(import.meta.url));
674
722
  // Packed clients keep the daemon beside engine.js. Source-tree repository
@@ -827,7 +875,7 @@ export class EngineClient {
827
875
  catch {
828
876
  if (!allowSpawn)
829
877
  return;
830
- const nodePath = process.env.KIBI_NODE_PATH ?? "node";
878
+ const nodePath = daemonNodePath();
831
879
  const entry = daemonEntry();
832
880
  const lockPath = engineStartLockPath(this.workspaceRoot, this.branch);
833
881
  const startDeadline = Date.now() + this.timeout;
@@ -915,6 +963,10 @@ export class EngineClient {
915
963
  }
916
964
  attachSocket(socket) {
917
965
  this.inputBuffer = Buffer.alloc(0);
966
+ // An idle connection must not keep its client alive: a host that is done
967
+ // with an MCP server or CLI command lets it exit while the shared daemon
968
+ // keeps serving. request() holds the socket while a reply is pending.
969
+ socket.unref();
918
970
  socket.on("data", (chunk) => {
919
971
  if (this.socket !== socket)
920
972
  return;
@@ -983,10 +1035,13 @@ export class EngineClient {
983
1035
  release = resolve;
984
1036
  });
985
1037
  await previous;
1038
+ let held = null;
986
1039
  try {
987
1040
  const socket = this.socket;
988
1041
  if (socket === null || socket.destroyed)
989
1042
  throw new Error("Kibi engine is not connected");
1043
+ socket.ref();
1044
+ held = socket;
990
1045
  const id = ++this.requestId;
991
1046
  const limits = this.readLimits !== undefined &&
992
1047
  READ_LIMITED_METHODS.has(request.method)
@@ -1039,6 +1094,8 @@ export class EngineClient {
1039
1094
  return value;
1040
1095
  }
1041
1096
  finally {
1097
+ if (held !== null && this.pending.size === 0)
1098
+ held.unref();
1042
1099
  release();
1043
1100
  }
1044
1101
  }
@@ -1301,6 +1358,7 @@ export class EngineClient {
1301
1358
  return 0;
1302
1359
  }
1303
1360
  }
1361
+ /** Resolves false when no daemon answered and none was started. */
1304
1362
  async stop(startIfMissing = true) {
1305
1363
  const socketPath = engineSocketPath(this.workspaceRoot, this.branch);
1306
1364
  if (!this.isRunning()) {
@@ -1309,14 +1367,29 @@ export class EngineClient {
1309
1367
  }
1310
1368
  catch {
1311
1369
  if (!startIfMissing)
1312
- return;
1370
+ return false;
1313
1371
  throw new Error("Unable to start Kibi engine for stop request");
1314
1372
  }
1315
1373
  }
1316
1374
  if (!this.isRunning() && existsSync(socketPath)) {
1317
1375
  throw new Error(`Kibi engine socket remains present but is not reachable: ${socketPath}`);
1318
1376
  }
1377
+ // A draining daemon has no listener but still counts as stopped here.
1378
+ const found = this.isRunning() || this.daemonProcessAlive();
1319
1379
  await this.shutdownConnectedDaemon();
1380
+ return found;
1381
+ }
1382
+ daemonProcessAlive() {
1383
+ const pid = this.getPid();
1384
+ if (pid <= 0)
1385
+ return false;
1386
+ try {
1387
+ process.kill(pid, 0);
1388
+ return true;
1389
+ }
1390
+ catch {
1391
+ return false;
1392
+ }
1320
1393
  }
1321
1394
  async terminate() {
1322
1395
  // Closing a client connection releases the engine; the daemon remains
@@ -1643,7 +1716,15 @@ export async function runEngineDaemon(requestedOptions) {
1643
1716
  : { maxOutputBytes: options.maxOutputBytes }),
1644
1717
  });
1645
1718
  const session = new EngineSession(prolog, branchPath);
1646
- await session.boot();
1719
+ try {
1720
+ await session.boot();
1721
+ }
1722
+ catch (error) {
1723
+ // A failed boot (store_locked, a module load error) leaves the SWI child
1724
+ // running, which keeps this daemon alive with no socket.
1725
+ await prolog.terminate().catch(() => undefined);
1726
+ throw error;
1727
+ }
1647
1728
  let attachedIdentity = readEngineAttachmentIdentity(branchPath);
1648
1729
  const serverPrologIdentity = engineSwiplIdentity();
1649
1730
  const serverPackageVersions = enginePackageVersions();
@@ -2099,7 +2180,12 @@ export async function runEngineDaemon(requestedOptions) {
2099
2180
  return result;
2100
2181
  }
2101
2182
  case "status":
2102
- return prolog.query("kb_storage_status(Status), atom_json_dict(Json, Status, [])");
2183
+ // Qualified: kb.pl loads library(http/json), but SWI-Prolog 9.0 does
2184
+ // not autoload it into `user`, where its toplevel then waits on a
2185
+ // "correct to kb:json_write_dict?" prompt instead of answering. A
2186
+ // string binding reaches the client as JSON text; an atom would
2187
+ // arrive Prolog-quoted and fail to parse.
2188
+ return prolog.query("kb_storage_status(Status), with_output_to(string(Json), json:json_write_dict(current_output, Status, [width(0)]))");
2103
2189
  case "checkpoint": {
2104
2190
  queryCache.clear();
2105
2191
  freshnessCache = null;
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/extractors/manifest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/extractors/manifest.ts"],"names":[],"mappings":"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"}
@@ -21,7 +21,7 @@ import * as path from "node:path";
21
21
  import { load as parseYAML } from "js-yaml";
22
22
  import { normalizeEntityOrigin, } from "../public/entity-origin.js";
23
23
  import { DEFAULT_COORDINATES_PATH } from "../utils/manifest-paths.js";
24
- import { normalizeRepoRelativePath } from "../utils/repo-relative-path.js";
24
+ import { normalizeRepoRelativePath, resolveWorkspaceSourceAbsolute, } from "../utils/repo-relative-path.js";
25
25
  import { mergeCoordinatesWithManifest, parseCoordinateArtifact, } from "./symbol-coordinates.js";
26
26
  const VALID_RELATIONSHIP_TYPES = new Set([
27
27
  "depends_on",
@@ -314,10 +314,8 @@ function sourceTextResolver(manifestPath) {
314
314
  return (sourceFile) => {
315
315
  let resolved = null;
316
316
  for (const base of bases) {
317
- const absolute = path.isAbsolute(sourceFile)
318
- ? sourceFile
319
- : path.resolve(base, sourceFile);
320
- if (!existsSync(absolute))
317
+ const absolute = resolveWorkspaceSourceAbsolute(base, sourceFile);
318
+ if (absolute === null || !existsSync(absolute))
321
319
  continue;
322
320
  try {
323
321
  const content = readFileSync(absolute, "utf8");
@@ -1 +1 @@
1
- {"version":3,"file":"symbol-coordinates.d.ts","sourceRoot":"","sources":["../../src/extractors/symbol-coordinates.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"symbol-coordinates.d.ts","sourceRoot":"","sources":["../../src/extractors/symbol-coordinates.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { existsSync, readFileSync } from "node:fs";
3
- import * as path from "node:path";
4
3
  import { dump as dumpYAML, load as parseYAML } from "js-yaml";
4
+ import { resolveWorkspaceSourceAbsolute } from "../utils/repo-relative-path.js";
5
5
  /**
6
6
  * Format version of the generated coordinate artifact. Version 2 binds every
7
7
  * record to the extraction identity that produced it so stale coordinates can
@@ -299,10 +299,8 @@ function manifestSourceFile(record) {
299
299
  return undefined;
300
300
  }
301
301
  function defaultResolveSourceText(sourceFile) {
302
- const absolute = path.isAbsolute(sourceFile)
303
- ? sourceFile
304
- : path.resolve(process.cwd(), sourceFile);
305
- if (!existsSync(absolute))
302
+ const absolute = resolveWorkspaceSourceAbsolute(process.cwd(), sourceFile);
303
+ if (absolute === null || !existsSync(absolute))
306
304
  return null;
307
305
  try {
308
306
  const content = readFileSync(absolute, "utf8");
@@ -1 +1 @@
1
- {"version":3,"file":"symbols-coordinator.d.ts","sourceRoot":"","sources":["../../src/extractors/symbols-coordinator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"symbols-coordinator.d.ts","sourceRoot":"","sources":["../../src/extractors/symbols-coordinator.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,7 @@
18
18
  import * as fs from "node:fs";
19
19
  import * as path from "node:path";
20
20
  import { createMaintenanceSourceAnalysisService } from "../plugins/maintenance-source-analysis.js";
21
+ import { resolveWorkspaceSourceAbsolute } from "../utils/repo-relative-path.js";
21
22
  import { createSourceAnalysisService, } from "../plugins/source-analysis-service.js";
22
23
  import { extensionLanguage, isTsJsSourcePath, } from "../plugins/source-classification.js";
23
24
  import { createTsMorphSourceAnalysisProvider, enrichSymbolCoordinatesWithTsMorph, } from "./symbols-ts.js";
@@ -230,10 +231,8 @@ function enrichWithRegexHeuristic(entry, absolutePath) {
230
231
  function resolveSourcePath(sourceFile, workspaceRoot) {
231
232
  if (!sourceFile)
232
233
  return null;
233
- const absolutePath = path.isAbsolute(sourceFile)
234
- ? sourceFile
235
- : path.resolve(workspaceRoot, sourceFile);
236
- if (!fs.existsSync(absolutePath))
234
+ const absolutePath = resolveWorkspaceSourceAbsolute(workspaceRoot, sourceFile);
235
+ if (absolutePath === null || !fs.existsSync(absolutePath))
237
236
  return null;
238
237
  return { absolutePath };
239
238
  }
@@ -1 +1 @@
1
- {"version":3,"file":"symbol-granularity.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/symbol-granularity.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAYjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AA0BpD;;;;GAIG;AAEH,eAAO,MAAM,4BAA4B,iCAAiC,CAAC;AA+B3E,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAC1C,aAAa,EAAE,SAAS,iBAAiB,EAAE,EAC3C,OAAO,EAAE,gBAAgB,EACzB,MAAM,CAAC,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,GAC3E,OAAO,CAAC,IAAI,CAAC,CAiDf"}
1
+ {"version":3,"file":"symbol-granularity.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/symbol-granularity.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAajF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AA0BpD;;;;GAIG;AAEH,eAAO,MAAM,4BAA4B,iCAAiC,CAAC;AA+B3E,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAC1C,aAAa,EAAE,SAAS,iBAAiB,EAAE,EAC3C,OAAO,EAAE,gBAAgB,EACzB,MAAM,CAAC,EAAE,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC,GAC3E,OAAO,CAAC,IAAI,CAAC,CAmDf"}
@@ -1,6 +1,6 @@
1
- import path from "node:path";
2
1
  import { collectGranularityCandidates } from "kibi-plugin-builtin";
3
2
  import { InputError } from "../../cli-errors.js";
3
+ import { resolveWorkspaceSourceAbsolute } from "../../utils/repo-relative-path.js";
4
4
  import { ALLOWED_GRANULARITY_REASONS_PROSE, coarseLinkBehavioralNames, getBehavioralSymbolNames, getNonBehavioralSymbolNames, inferSymbolRole, isAllowedGranularityReason, isTraceabilityRelationshipType, } from "../../public/symbol-granularity.js";
5
5
  function candidate(name, kind) {
6
6
  return { name, kind, role: inferSymbolRole(kind) };
@@ -66,9 +66,9 @@ export async function validateSymbolGranularity(payload, relationships, context,
66
66
  const fs = context.fs;
67
67
  if (fs === undefined)
68
68
  return;
69
- const sourcePath = path.isAbsolute(entity.sourceFile)
70
- ? entity.sourceFile
71
- : path.resolve(context.workspaceRoot, entity.sourceFile);
69
+ const sourcePath = resolveWorkspaceSourceAbsolute(context.workspaceRoot, entity.sourceFile);
70
+ if (sourcePath === null)
71
+ return;
72
72
  let content;
73
73
  try {
74
74
  const stat = await fs.stat(sourcePath);
@@ -1 +1 @@
1
- {"version":3,"file":"symbol-refresh.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/symbol-refresh.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAgBjF,MAAM,MAAM,sBAAsB,GAC9B,SAAS,GACT,WAAW,GACX,SAAS,GACT,WAAW,CAAC;AAGhB,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,sBAAsB,CAAC;IAC1C,QAAQ,CAAC,WAAW,CAAC,EAAE,0BAA0B,CAAC;CACnD,CAAC;AAGF,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,IAAI,IAAI,CAAC;CAClB,CAAC;AAEF,KAAK,qBAAqB,GAAG,CAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,gBAAgB,KACtB,OAAO,CAAC,aAAa,CAAC,CAAC;AAsD5B,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GAAG,IAAI,GACpB,IAAI,CAMN;AAiPD,4EAA4E;AAC5E,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,aAAa,CAAC,CASxB;AAED,yEAAyE;AAEzE,wBAAsB,gCAAgC,CACpD,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,aAAa,CAAC,CAGxB;AAED;;;GAGG;AAEH,wBAAsB,mCAAmC,CACvD,QAAQ,EAAE,MAAM,EAChB,oBAAoB,EAAE,MAAM,EAC5B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,aAAa,CAAC,CAOxB;AAGD,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,qBAAqB,GAAG,SAAS,GACzC,IAAI,CAEN"}
1
+ {"version":3,"file":"symbol-refresh.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/symbol-refresh.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAiBjF,MAAM,MAAM,sBAAsB,GAC9B,SAAS,GACT,WAAW,GACX,SAAS,GACT,WAAW,CAAC;AAGhB,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,sBAAsB,CAAC;IAC1C,QAAQ,CAAC,WAAW,CAAC,EAAE,0BAA0B,CAAC;CACnD,CAAC;AAGF,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,IAAI,IAAI,CAAC;CAClB,CAAC;AAEF,KAAK,qBAAqB,GAAG,CAC3B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,gBAAgB,KACtB,OAAO,CAAC,aAAa,CAAC,CAAC;AAqD5B,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,GAAG,IAAI,GACpB,IAAI,CAMN;AAiPD,4EAA4E;AAC5E,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,aAAa,CAAC,CASxB;AAED,yEAAyE;AAEzE,wBAAsB,gCAAgC,CACpD,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,aAAa,CAAC,CAGxB;AAED;;;GAGG;AAEH,wBAAsB,mCAAmC,CACvD,QAAQ,EAAE,MAAM,EAChB,oBAAoB,EAAE,MAAM,EAC5B,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,aAAa,CAAC,CAOxB;AAGD,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,qBAAqB,GAAG,SAAS,GACzC,IAAI,CAEN"}
@@ -6,6 +6,7 @@ import { CoordinateArtifactError, coarseCoordinateSpan, coordinateIdentityHash,
6
6
  import { enrichSymbolCoordinates } from "../../public/extractors/symbols-coordinator.js";
7
7
  import { isCoarseGranularityReason } from "../../public/symbol-granularity.js";
8
8
  import { CANONICAL_ENTITY_PATHS } from "../../utils/kb-paths.js";
9
+ import { resolveWorkspaceSourceAbsolute } from "../../utils/repo-relative-path.js";
9
10
  import { withSymbolCompilerLock } from "./symbol-compiler-lock.js";
10
11
  function record(value) {
11
12
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -29,9 +30,9 @@ function artifactPathFor(manifest) {
29
30
  return path.join(path.dirname(manifest), "symbol-coordinates.yaml");
30
31
  }
31
32
  function sourceTextFor(sourceFile, workspaceRoot) {
32
- const absolute = path.isAbsolute(sourceFile)
33
- ? sourceFile
34
- : path.resolve(workspaceRoot, sourceFile);
33
+ const absolute = resolveWorkspaceSourceAbsolute(workspaceRoot, sourceFile);
34
+ if (absolute === null)
35
+ return null;
35
36
  try {
36
37
  return readFileSync(absolute, "utf8");
37
38
  }
@@ -228,6 +228,9 @@ export { isAllowedGranularityReason };
228
228
  * artifact, but the engine never merges coordinates for KB-internal paths —
229
229
  * coverage then reports missing_symbol_coordinates forever with no signal.
230
230
  * Reject the configuration at upsert time instead.
231
+ *
232
+ * Also reject absolute paths and `..` escapes so coordinate refresh cannot be
233
+ * used as a workspace-escape oracle against files outside the repository.
231
234
  */
232
235
  function validateSymbolSourceFile(entity) {
233
236
  if (entity.type !== "symbol")
@@ -239,6 +242,14 @@ function validateSymbolSourceFile(entity) {
239
242
  if (normalized === ".kb" || normalized.startsWith(".kb/")) {
240
243
  throw new Error(`Entity validation failed: symbol sourceFile must point at a real code file in the workspace, not into the knowledge base ('${sourceFile}'). Coordinates for .kb/ paths are never merged into the engine, so coverage would report missing_symbol_coordinates permanently. Point the symbol at the implementing or verifying code file instead.`);
241
244
  }
245
+ // Lexical confinement (no workspace root needed): absolute paths and `..`
246
+ // segments are never valid authored sourceFile values.
247
+ if (normalized.startsWith("/") ||
248
+ /^[A-Za-z]:\//.test(normalized) ||
249
+ normalized.startsWith("//") ||
250
+ normalized.split("/").includes("..")) {
251
+ throw new Error(`Entity validation failed: symbol sourceFile must be a workspace-relative path ('${sourceFile}'). Absolute paths and '..' escapes are rejected so coordinate refresh cannot read files outside the repository.`);
252
+ }
242
253
  }
243
254
  /**
244
255
  * proof_exempt parks a current requirement outside E2E-proof scope. Without a
@@ -1,8 +1,8 @@
1
1
  export declare const qualifiedSourceAnalyzers: readonly [{
2
2
  readonly packageName: "kibi-plugin-treesitter";
3
- readonly version: "2.0.0";
3
+ readonly version: "2.0.1";
4
4
  readonly files: {
5
- readonly "SBOM.spdx.json": "579e1574f09042cf85d9fa76837555c06a15f133f321fc0800fadd2f9539c52c";
5
+ readonly "SBOM.spdx.json": "8e7136ff7d28e8acb32e864baa9f4e69eee02620550ed7f0551c115759de8561";
6
6
  readonly "THIRD_PARTY_NOTICES.md": "0b1ede96cb261dab73fd1ec8c51d7bb5b2492eed0502f6c10ed071736daa263c";
7
7
  readonly "assets/queries/bash.scm": "6ca535e8fe652b51203ac272831881dab001f7ac508e50551bc2cdc4a15d7b6c";
8
8
  readonly "assets/queries/c.scm": "774ca67cfe23b0e0d1d3a4f01788049a822beb1311feee72b20a595a37be1e28";
@@ -32,13 +32,13 @@ export declare const qualifiedSourceAnalyzers: readonly [{
32
32
  readonly "assets/tree-sitter-ruby.wasm": "09a96427d7c72f0613ed470cd9812223fc4a91d6a9c025c0235cc6bd59ff96f4";
33
33
  readonly "assets/tree-sitter-rust.wasm": "f65f354215611fd94ad34134b3427eb3d58cbb745df7b6509ba722184db73d57";
34
34
  readonly "assets/tree-sitter-terraform.release.wasm": "59dbcbb0f08eb78b78f37510834559a48ce5c9d4866c978d62c6390796461cb5";
35
- readonly "catalog.json": "6c1101d0e831ea11f1002edf4baeca88521ac6f4c18a2e1c64f2f030f8bf6bba";
36
- readonly "dist/analysis-worker.js": "75a1e646f636c1d1ace9ae22a9141a51e94bddc70203bed08de7bd13dae1764e";
35
+ readonly "catalog.json": "af91adedf93039b54471c99fdd4bbf10a2f3ce716324be6935a6dbdd4aee2d0b";
36
+ readonly "dist/analysis-worker.js": "7e87c177a5893e7edd5b6fb2b2798aadf22831c092af96026a2de130034116f5";
37
37
  readonly "dist/catalog.js": "460243c48cb6a03b8c7971273729d8a1134955186978b6c0d04182c71960ebff";
38
38
  readonly "dist/extractor.js": "1d8cd819e7ec8fcc291a44e5ffe4ccfe77099301677913fcfe0d92e7ce971f33";
39
39
  readonly "dist/index.js": "adc03d77d94c0133b3188950b35f79db19e447cf7bfa1f7e1cf1f5c97a582a44";
40
40
  readonly "dist/performance-timing.js": "56cce530f627c8fd079e8ec070322f84378ae50c40a6765d88b418850692940b";
41
- readonly "integrity.json": "a77eb4b614452f158202b3f8aa91b91750dd2ad94693cc9c375460ec5b80c48b";
41
+ readonly "integrity.json": "d203e1e7b1e25264a56ce85a1d99b4b09ddcb093ffd4a21d591045dc3deeff3f";
42
42
  readonly "licenses/tree-sitter-bash-MIT.txt": "49bf33cf78ef5897e4e161ce1517df7de1ae5042a65b6bcfd44401e0fc606559";
43
43
  readonly "licenses/tree-sitter-c-MIT.txt": "2e0110e07abef7c2548b26ec9d6969775617ca539a0dc8dbeeb14d6452c711d1";
44
44
  readonly "licenses/tree-sitter-c-sharp-MIT.txt": "778fb7d63b8c1844da315648c02f325c4713a6f4a5d19644fd413421422776d3";
@@ -51,7 +51,7 @@ export declare const qualifiedSourceAnalyzers: readonly [{
51
51
  readonly "licenses/tree-sitter-ruby-MIT.txt": "9c99b99e93d3c6461bef9f6bac45d17b8bf014172625c24f76319bbd235a7b80";
52
52
  readonly "licenses/tree-sitter-rust-MIT.txt": "31d5b6f4243d5c7c6e1c4ebbbb9f6407bd1457a08bcc4f706521710341acba36";
53
53
  readonly "licenses/web-tree-sitter-MIT.txt": "c5cfb43042b6b72045f4ba997834d0a7786d2793d91680868b5815b39f14fc78";
54
- readonly "package.json": "db0277b9bfd47a242dd457bd1d4fb29bf126121734c9b393ffe6b91af5e5919b";
54
+ readonly "package.json": "094ab574489d2d0994b12acdf5d70a227f7b37cf8a9b40965d7ee5c440b5aae0";
55
55
  };
56
56
  readonly dependencies: readonly [{
57
57
  readonly packageName: "web-tree-sitter";
@@ -4,9 +4,9 @@
4
4
  export const qualifiedSourceAnalyzers = [
5
5
  {
6
6
  packageName: "kibi-plugin-treesitter",
7
- version: "2.0.0",
7
+ version: "2.0.1",
8
8
  files: {
9
- "SBOM.spdx.json": "579e1574f09042cf85d9fa76837555c06a15f133f321fc0800fadd2f9539c52c",
9
+ "SBOM.spdx.json": "8e7136ff7d28e8acb32e864baa9f4e69eee02620550ed7f0551c115759de8561",
10
10
  "THIRD_PARTY_NOTICES.md": "0b1ede96cb261dab73fd1ec8c51d7bb5b2492eed0502f6c10ed071736daa263c",
11
11
  "assets/queries/bash.scm": "6ca535e8fe652b51203ac272831881dab001f7ac508e50551bc2cdc4a15d7b6c",
12
12
  "assets/queries/c.scm": "774ca67cfe23b0e0d1d3a4f01788049a822beb1311feee72b20a595a37be1e28",
@@ -36,13 +36,13 @@ export const qualifiedSourceAnalyzers = [
36
36
  "assets/tree-sitter-ruby.wasm": "09a96427d7c72f0613ed470cd9812223fc4a91d6a9c025c0235cc6bd59ff96f4",
37
37
  "assets/tree-sitter-rust.wasm": "f65f354215611fd94ad34134b3427eb3d58cbb745df7b6509ba722184db73d57",
38
38
  "assets/tree-sitter-terraform.release.wasm": "59dbcbb0f08eb78b78f37510834559a48ce5c9d4866c978d62c6390796461cb5",
39
- "catalog.json": "6c1101d0e831ea11f1002edf4baeca88521ac6f4c18a2e1c64f2f030f8bf6bba",
40
- "dist/analysis-worker.js": "75a1e646f636c1d1ace9ae22a9141a51e94bddc70203bed08de7bd13dae1764e",
39
+ "catalog.json": "af91adedf93039b54471c99fdd4bbf10a2f3ce716324be6935a6dbdd4aee2d0b",
40
+ "dist/analysis-worker.js": "7e87c177a5893e7edd5b6fb2b2798aadf22831c092af96026a2de130034116f5",
41
41
  "dist/catalog.js": "460243c48cb6a03b8c7971273729d8a1134955186978b6c0d04182c71960ebff",
42
42
  "dist/extractor.js": "1d8cd819e7ec8fcc291a44e5ffe4ccfe77099301677913fcfe0d92e7ce971f33",
43
43
  "dist/index.js": "adc03d77d94c0133b3188950b35f79db19e447cf7bfa1f7e1cf1f5c97a582a44",
44
44
  "dist/performance-timing.js": "56cce530f627c8fd079e8ec070322f84378ae50c40a6765d88b418850692940b",
45
- "integrity.json": "a77eb4b614452f158202b3f8aa91b91750dd2ad94693cc9c375460ec5b80c48b",
45
+ "integrity.json": "d203e1e7b1e25264a56ce85a1d99b4b09ddcb093ffd4a21d591045dc3deeff3f",
46
46
  "licenses/tree-sitter-bash-MIT.txt": "49bf33cf78ef5897e4e161ce1517df7de1ae5042a65b6bcfd44401e0fc606559",
47
47
  "licenses/tree-sitter-c-MIT.txt": "2e0110e07abef7c2548b26ec9d6969775617ca539a0dc8dbeeb14d6452c711d1",
48
48
  "licenses/tree-sitter-c-sharp-MIT.txt": "778fb7d63b8c1844da315648c02f325c4713a6f4a5d19644fd413421422776d3",
@@ -55,7 +55,7 @@ export const qualifiedSourceAnalyzers = [
55
55
  "licenses/tree-sitter-ruby-MIT.txt": "9c99b99e93d3c6461bef9f6bac45d17b8bf014172625c24f76319bbd235a7b80",
56
56
  "licenses/tree-sitter-rust-MIT.txt": "31d5b6f4243d5c7c6e1c4ebbbb9f6407bd1457a08bcc4f706521710341acba36",
57
57
  "licenses/web-tree-sitter-MIT.txt": "c5cfb43042b6b72045f4ba997834d0a7786d2793d91680868b5815b39f14fc78",
58
- "package.json": "db0277b9bfd47a242dd457bd1d4fb29bf126121734c9b393ffe6b91af5e5919b",
58
+ "package.json": "094ab574489d2d0994b12acdf5d70a227f7b37cf8a9b40965d7ee5c440b5aae0",
59
59
  },
60
60
  dependencies: [
61
61
  {
@@ -1 +1 @@
1
- {"version":3,"file":"error-terms.d.ts","sourceRoot":"","sources":["../../src/prolog/error-terms.ts"],"names":[],"mappings":"AAoBA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,wBAAwB,oBAAoB,CAAC;AAG1D,MAAM,MAAM,eAAe,GACvB,gBAAgB,GAChB,cAAc,GACd,mBAAmB,GACnB,kBAAkB,GAClB,sBAAsB,GACtB,eAAe,GACf,kBAAkB,CAAC;AAGvB,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAGH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAGH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,KAAK,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC3B,YAAY,CAAC,EAAE,uBAAuB,CAAC;IACvC,SAAS,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC3C,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,yEAAyE;AAEzE,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,GACX,iBAAiB,GAAG,IAAI,CAK1B;AAED,kFAAkF;AAElF,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,GACf,iBAAiB,GAAG,IAAI,CAsG1B"}
1
+ {"version":3,"file":"error-terms.d.ts","sourceRoot":"","sources":["../../src/prolog/error-terms.ts"],"names":[],"mappings":"AAqBA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,wBAAwB,oBAAoB,CAAC;AAG1D,MAAM,MAAM,eAAe,GACvB,gBAAgB,GAChB,cAAc,GACd,mBAAmB,GACnB,kBAAkB,GAClB,sBAAsB,GACtB,eAAe,GACf,kBAAkB,CAAC;AAGvB,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAGH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAGH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,KAAK,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC3B,YAAY,CAAC,EAAE,uBAAuB,CAAC;IACvC,SAAS,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC3C,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,yEAAyE;AAEzE,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,GACX,iBAAiB,GAAG,IAAI,CAK1B;AAED,kFAAkF;AAElF,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,GACf,iBAAiB,GAAG,IAAI,CAsG1B"}
@@ -16,6 +16,7 @@
16
16
  along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
  */
18
18
  import { splitTopLevelGeneral } from "./codec.js";
19
+ import { describeLockHolderPid } from "./store-lock.js";
19
20
  /**
20
21
  * Structured transport for Prolog errors.
21
22
  *
@@ -88,7 +89,7 @@ export function parsePrologErrorTerm(termText) {
88
89
  const holder = detail.owner;
89
90
  const holderSummary = holder === null
90
91
  ? "an unidentified holder"
91
- : `pid ${holder.pid ?? "?"}${holder.workspaceRoot !== undefined ? ` for ${holder.workspaceRoot}` : ""}${holder.startedAt !== undefined ? ` since ${holder.startedAt}` : ""}`;
92
+ : `${holder.pid === undefined ? "pid ?" : describeLockHolderPid(holder.pid)}${holder.workspaceRoot !== undefined ? ` for ${holder.workspaceRoot}` : ""}${holder.startedAt !== undefined ? ` since ${holder.startedAt}` : ""}`;
92
93
  return {
93
94
  code: "permission_denied",
94
95
  storeLocked: detail,
@@ -319,16 +320,21 @@ function parseEntityRole(message) {
319
320
  return "target";
320
321
  return undefined;
321
322
  }
322
- /** Strip SWI quoted-atom quoting and unescape standard character escapes. */
323
+ const PROLOG_ESCAPES = { n: "\n", t: "\t" };
324
+ /**
325
+ * Strip SWI quoted-atom or string quoting and unescape standard character
326
+ * escapes. Strings matter for store_locked: kb.pl reads the owner journal
327
+ * with read_file_to_string, so the owner arrives double-quoted.
328
+ */
323
329
  function unquoteAtom(value) {
324
330
  const trimmed = value.trim();
325
- if (trimmed.length >= 2 && trimmed.startsWith("'") && trimmed.endsWith("'")) {
326
- const inner = trimmed.slice(1, -1);
327
- return inner
328
- .replace(/\\'/g, "'")
329
- .replace(/\\\\/g, "\\")
330
- .replace(/\\n/g, "\n")
331
- .replace(/\\t/g, "\t");
331
+ const quote = trimmed[0];
332
+ if (trimmed.length >= 2 &&
333
+ (quote === "'" || quote === '"') &&
334
+ trimmed.endsWith(quote)) {
335
+ return trimmed
336
+ .slice(1, -1)
337
+ .replace(/\\(.)/gs, (_, char) => PROLOG_ESCAPES[char] ?? char);
332
338
  }
333
339
  return trimmed;
334
340
  }
@@ -3,6 +3,17 @@ import type { PrologStoreLockOwner } from "./error-terms.js";
3
3
  /** Linux boot id; guards against PID reuse across reboots. Null elsewhere. */
4
4
  export declare function currentBootId(): string | null;
5
5
  export declare function isProcessAlive(pid: number): boolean;
6
+ /**
7
+ * The process to stop for a store lock holder. The lock records the engine's
8
+ * SWI-Prolog child; its parent (the daemon, or another Kibi process hosting
9
+ * the session) is what a user ends or stops.
10
+ */
11
+ export declare function lockHolderProcess(pid: number): {
12
+ pid: number;
13
+ prologPid?: number;
14
+ };
15
+ /** "pid N", naming the owning Kibi process when N is its SWI-Prolog child. */
16
+ export declare function describeLockHolderPid(pid: number): string;
6
17
  export type StoreLockHolderState = "self" | "alive" | "dead" | "unknown";
7
18
  export declare function classifyStoreLockHolder(owner: PrologStoreLockOwner | null): StoreLockHolderState;
8
19
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"store-lock.d.ts","sourceRoot":"","sources":["../../src/prolog/store-lock.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,KAAK,EAAqB,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAgBhF,8EAA8E;AAC9E,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAa7C;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAUnD;AAED,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAEzE,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,oBAAoB,GAAG,IAAI,GACjC,oBAAoB,CAYtB;AAED;;;;;GAKG;AAEH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,GAChB;IAAE,KAAK,EAAE,oBAAoB,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA4B7D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAWzD;AAED,qEAAqE;AACrE,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AAEnE;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,QAAsB,CAAC;AAElE,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd,CAAC,CAAC;AAEH;;;GAGG;AAEH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,MAAM,EAAE,MAAM,EACd,EAAE,GAAE,IAAiB,GACpB,IAAI,CAUN;AAED,iFAAiF;AAEjF,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,GAChB,uBAAuB,GAAG,IAAI,CAmBhC;AAED,sEAAsE;AAEtE,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ9D;AAED;;;;;;;;;;;;;;;GAeG;AAEH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,CAerE;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,yEAAyE;AACzE,eAAO,MAAM,gCAAgC,yCACL,CAAC;AAoCzC;;;;;;;;;;;;;;;;;GAiBG;AAEH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,oBAAoB,GAAG,IAAI,EAClC,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,IAAI,CAcf;AAED;;;;;;GAMG;AAEH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,oBAAoB,GAAG,IAAI,EAClC,OAAO,GAAE;IAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5C,yBAAyB,CA+B3B;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;CACxD;AAED;;;;;;GAMG;AAEH,wBAAsB,iCAAiC,CACrD,MAAM,EAAE,qBAAqB,EAC7B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,WAAW,CAAC,CAmCtB"}
1
+ {"version":3,"file":"store-lock.d.ts","sourceRoot":"","sources":["../../src/prolog/store-lock.ts"],"names":[],"mappings":"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"}