kibi-runtime 2.10.0 → 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -6737,19 +6737,56 @@ var init_engine_limits = __esm(() => {
6737
6737
  };
6738
6738
  });
6739
6739
 
6740
+ // ../cli/dist/package-versions.js
6741
+ import { readFileSync as readFileSync2 } from "node:fs";
6742
+ import { createRequire as createRequire2 } from "node:module";
6743
+ import path2 from "node:path";
6744
+ import { fileURLToPath } from "node:url";
6745
+ function manifestVersion(manifestPath, expectedName) {
6746
+ try {
6747
+ const manifest = JSON.parse(readFileSync2(manifestPath, "utf8"));
6748
+ return manifest.name === expectedName && typeof manifest.version === "string" ? manifest.version : undefined;
6749
+ } catch {
6750
+ return;
6751
+ }
6752
+ }
6753
+ function cliVersion() {
6754
+ if (true)
6755
+ return "2.13.0";
6756
+ return manifestVersion(path2.join(moduleDirectory, "..", "package.json"), "kibi-cli") ?? "unknown";
6757
+ }
6758
+ function coreVersion() {
6759
+ try {
6760
+ const resolved = manifestVersion(require2.resolve("kibi-core/package.json"), "kibi-core");
6761
+ if (resolved)
6762
+ return resolved;
6763
+ } catch {}
6764
+ return manifestVersion(path2.join(moduleDirectory, "..", "..", "core", "package.json"), "kibi-core") ?? "unknown";
6765
+ }
6766
+ function kibiPackageVersions() {
6767
+ const override = process.env.KIBI_PACKAGE_VERSIONS;
6768
+ return override !== undefined && override.length > 0 ? override : KIBI_BUILT_PACKAGE_VERSIONS;
6769
+ }
6770
+ var require2, moduleDirectory, KIBI_BUILT_PACKAGE_VERSIONS;
6771
+ var init_package_versions = __esm(() => {
6772
+ require2 = createRequire2(import.meta.url);
6773
+ moduleDirectory = path2.dirname(fileURLToPath(import.meta.url));
6774
+ KIBI_BUILT_PACKAGE_VERSIONS = `kibi-cli@${cliVersion()},kibi-core@${coreVersion()}`;
6775
+ });
6776
+
6740
6777
  // ../cli/dist/performance-trace.js
6741
6778
  import { constants } from "node:fs";
6742
6779
  import { closeSync, existsSync as existsSync2, lstatSync, openSync, realpathSync, statSync, writeSync } from "node:fs";
6743
- import path2 from "node:path";
6780
+ import path3 from "node:path";
6744
6781
  function isWithin(parent, candidate) {
6745
- const relative = path2.relative(parent, candidate);
6746
- return relative === "" || relative !== ".." && !relative.startsWith(`..${path2.sep}`) && !path2.isAbsolute(relative);
6782
+ const relative = path3.relative(parent, candidate);
6783
+ return relative === "" || relative !== ".." && !relative.startsWith(`..${path3.sep}`) && !path3.isAbsolute(relative);
6747
6784
  }
6748
6785
  function privateTraceFile() {
6749
6786
  if (process.env[KIBI_PERF_TIMINGS_ENV] !== "1")
6750
6787
  return null;
6751
6788
  const configuredDirectory = process.env[KIBI_PERF_TRACE_DIR_ENV];
6752
- if (!configuredDirectory || !path2.isAbsolute(configuredDirectory))
6789
+ if (!configuredDirectory || !path3.isAbsolute(configuredDirectory))
6753
6790
  return null;
6754
6791
  try {
6755
6792
  const directoryInfo = lstatSync(configuredDirectory);
@@ -6757,7 +6794,7 @@ function privateTraceFile() {
6757
6794
  return null;
6758
6795
  }
6759
6796
  const directory = realpathSync(configuredDirectory);
6760
- if (path2.resolve(configuredDirectory) !== directory)
6797
+ if (path3.resolve(configuredDirectory) !== directory)
6761
6798
  return null;
6762
6799
  const directoryStats = statSync(directory);
6763
6800
  if (typeof process.getuid !== "function" || directoryStats.uid !== process.getuid()) {
@@ -6769,7 +6806,7 @@ function privateTraceFile() {
6769
6806
  const currentDirectory = realpathSync(process.cwd());
6770
6807
  if (isWithin(currentDirectory, directory))
6771
6808
  return null;
6772
- const file = path2.join(directory, `kibi-performance-${process.pid}.jsonl`);
6809
+ const file = path3.join(directory, `kibi-performance-${process.pid}.jsonl`);
6773
6810
  let state = states.get(file);
6774
6811
  if (!state) {
6775
6812
  if (existsSync2(file))
@@ -7138,8 +7175,8 @@ var init_error_terms = () => {};
7138
7175
 
7139
7176
  // ../cli/dist/prolog/swipl-resolver.js
7140
7177
  import { execFileSync, spawnSync } from "node:child_process";
7141
- import { constants as constants2, accessSync, existsSync as existsSync3, readFileSync as readFileSync2, statSync as statSync2 } from "node:fs";
7142
- import path3 from "node:path";
7178
+ import { constants as constants2, accessSync, existsSync as existsSync3, readFileSync as readFileSync3, statSync as statSync2 } from "node:fs";
7179
+ import path4 from "node:path";
7143
7180
  import { BUNDLED_BINARY_PATH, MANIFEST_FILE, PLATFORM_PACKAGES, locatePlatformPackage, platformKey, sha256File, validateBuildManifest } from "kibi-swipl";
7144
7181
  function detectGlibc() {
7145
7182
  if (process.platform !== "linux")
@@ -7212,8 +7249,8 @@ function inspectBundle(deps) {
7212
7249
  const packageDir = deps.locatePackage(packageName);
7213
7250
  if (packageDir === undefined)
7214
7251
  return { kind: "missing", key, packageName };
7215
- const manifestPath = path3.join(packageDir, MANIFEST_FILE);
7216
- const binary = path3.join(packageDir, BUNDLED_BINARY_PATH);
7252
+ const manifestPath = path4.join(packageDir, MANIFEST_FILE);
7253
+ const binary = path4.join(packageDir, BUNDLED_BINARY_PATH);
7217
7254
  if (!existsSync3(manifestPath)) {
7218
7255
  if (!existsSync3(binary))
7219
7256
  return { kind: "empty", key, packageName };
@@ -7233,12 +7270,12 @@ function inspectBundle(deps) {
7233
7270
  let manifest;
7234
7271
  let packageJson;
7235
7272
  try {
7236
- manifest = JSON.parse(readFileSync2(manifestPath, "utf8"));
7273
+ manifest = JSON.parse(readFileSync3(manifestPath, "utf8"));
7237
7274
  } catch (error) {
7238
7275
  return corrupt(`${MANIFEST_FILE} is not valid JSON (${error instanceof Error ? error.message : String(error)})`);
7239
7276
  }
7240
7277
  try {
7241
- packageJson = JSON.parse(readFileSync2(path3.join(packageDir, "package.json"), "utf8"));
7278
+ packageJson = JSON.parse(readFileSync3(path4.join(packageDir, "package.json"), "utf8"));
7242
7279
  } catch (error) {
7243
7280
  return corrupt(`package.json is unreadable (${error instanceof Error ? error.message : String(error)})`);
7244
7281
  }
@@ -7261,7 +7298,7 @@ function inspectBundle(deps) {
7261
7298
  if (actual !== checked.binarySha256) {
7262
7299
  return corrupt(`${BUNDLED_BINARY_PATH} SHA-256 ${actual} does not match the manifest (${checked.binarySha256})`);
7263
7300
  }
7264
- const home = path3.join(packageDir, checked.home);
7301
+ const home = path4.join(packageDir, checked.home);
7265
7302
  let homeIsDirectory = false;
7266
7303
  try {
7267
7304
  homeIsDirectory = statSync2(home).isDirectory();
@@ -7303,10 +7340,10 @@ function probeVersion(bin, deps) {
7303
7340
  return { kind: "ok", version: parsed.version };
7304
7341
  }
7305
7342
  function findOnPath(env, deps) {
7306
- for (const directory of (env.PATH ?? "").split(path3.delimiter)) {
7307
- if (directory === "" || !path3.isAbsolute(directory))
7343
+ for (const directory of (env.PATH ?? "").split(path4.delimiter)) {
7344
+ if (directory === "" || !path4.isAbsolute(directory))
7308
7345
  continue;
7309
- const candidate = path3.join(directory, "swipl");
7346
+ const candidate = path4.join(directory, "swipl");
7310
7347
  if (!isExecutableFile(candidate))
7311
7348
  continue;
7312
7349
  const probe = probeVersion(candidate, deps);
@@ -7329,7 +7366,7 @@ function resolveFromEnv(override, deps) {
7329
7366
  });
7330
7367
  const packageName = key === undefined ? undefined : PLATFORM_PACKAGES[key].package;
7331
7368
  const invalid = (detail) => new SwiplResolutionError("swipl_env_invalid", `KIBI_SWIPL=${override} ${detail}. Set KIBI_SWIPL to the absolute path of a SWI-Prolog ${MINIMUM_SWIPL_MAJOR}.0+ executable, to "system" to use swipl from PATH, or unset it to use the bundled runtime.`, platform, packageName);
7332
- if (!path3.isAbsolute(override))
7369
+ if (!path4.isAbsolute(override))
7333
7370
  return fail(invalid("is not an absolute path"));
7334
7371
  if (!isExecutableFile(override)) {
7335
7372
  return fail(invalid("is not an executable file"));
@@ -7454,18 +7491,10 @@ var init_swipl_resolver = __esm(() => {
7454
7491
  // ../cli/dist/prolog.js
7455
7492
  import { spawn } from "node:child_process";
7456
7493
  import { existsSync as existsSync4 } from "node:fs";
7457
- import { createRequire as createRequire2 } from "node:module";
7458
- import path4 from "node:path";
7494
+ import { createRequire as createRequire3 } from "node:module";
7495
+ import path5 from "node:path";
7459
7496
  import { performance } from "node:perf_hooks";
7460
- import { fileURLToPath } from "node:url";
7461
- function packageVersion(packagePath) {
7462
- try {
7463
- const packageJson = require2(packagePath);
7464
- return typeof packageJson.version === "string" ? packageJson.version : "unknown";
7465
- } catch {
7466
- return "unknown";
7467
- }
7468
- }
7497
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
7469
7498
  function resolveKbPlPath() {
7470
7499
  const overrideKbPath = getKbPlPathOverride();
7471
7500
  if (overrideKbPath) {
@@ -7473,20 +7502,20 @@ function resolveKbPlPath() {
7473
7502
  }
7474
7503
  try {
7475
7504
  try {
7476
- return require2.resolve("kibi-core/src/kb.pl");
7505
+ return require3.resolve("kibi-core/src/kb.pl");
7477
7506
  } catch {
7478
- const coreMain = require2.resolve("kibi-core");
7479
- const coreDir = path4.dirname(coreMain);
7480
- return path4.join(coreDir, "src", "kb.pl");
7507
+ const coreMain = require3.resolve("kibi-core");
7508
+ const coreDir = path5.dirname(coreMain);
7509
+ return path5.join(coreDir, "src", "kb.pl");
7481
7510
  }
7482
7511
  } catch {}
7483
7512
  let currentDir = importMetaDir;
7484
- while (currentDir !== path4.dirname(currentDir)) {
7485
- const candidate = path4.join(currentDir, "packages", "core", "src", "kb.pl");
7513
+ while (currentDir !== path5.dirname(currentDir)) {
7514
+ const candidate = path5.join(currentDir, "packages", "core", "src", "kb.pl");
7486
7515
  if (existsSync4(candidate)) {
7487
7516
  return candidate;
7488
7517
  }
7489
- currentDir = path4.dirname(currentDir);
7518
+ currentDir = path5.dirname(currentDir);
7490
7519
  }
7491
7520
  throw new Error("Unable to resolve kb.pl. Expected kibi-core to be installed (node_modules) " + "or to be running inside the monorepo checkout.");
7492
7521
  }
@@ -7568,7 +7597,7 @@ class PrologProcess {
7568
7597
  ...launch.env,
7569
7598
  KIBI_RUNTIME_NAME: process.versions.bun !== undefined ? "bun" : "node",
7570
7599
  KIBI_RUNTIME_VERSION: process.versions.bun ?? process.versions.node ?? "unknown",
7571
- KIBI_PACKAGE_VERSIONS: process.env.KIBI_PACKAGE_VERSIONS ?? KIBI_PACKAGE_VERSIONS
7600
+ KIBI_PACKAGE_VERSIONS: kibiPackageVersions()
7572
7601
  }
7573
7602
  });
7574
7603
  this.clearQueryBuffers();
@@ -7689,7 +7718,7 @@ writeln('${INTERACTIVE_QUERY_FRAME_END}').
7689
7718
  console.error(`[prolog debug] timeout: ${msg}`);
7690
7719
  const runtime = this.errorBuffer.split(`
7691
7720
  `).find((line) => line.includes("__KIBI_RUNTIME__"));
7692
- console.error(`[prolog debug] runtime=${runtime ?? "unknown"} packages=${process.env.KIBI_PACKAGE_VERSIONS ?? KIBI_PACKAGE_VERSIONS}`);
7721
+ console.error(`[prolog debug] runtime=${runtime ?? "unknown"} packages=${kibiPackageVersions()}`);
7693
7722
  }
7694
7723
  settle();
7695
7724
  this.terminationReason = `query timeout: ${goalLabel}`;
@@ -7888,7 +7917,7 @@ writeln('${INTERACTIVE_QUERY_FRAME_END}').
7888
7917
  ].join(", ");
7889
7918
  const runtimeName = process.versions.bun !== undefined ? "bun" : "node";
7890
7919
  const runtimeVersion = process.versions.bun ?? process.versions.node ?? "unknown";
7891
- const packageVersions = process.env.KIBI_PACKAGE_VERSIONS ?? KIBI_PACKAGE_VERSIONS;
7920
+ const packageVersions = kibiPackageVersions();
7892
7921
  let child;
7893
7922
  try {
7894
7923
  const launch = this.launchTarget();
@@ -8264,19 +8293,15 @@ writeln('${INTERACTIVE_QUERY_FRAME_END}').
8264
8293
  }
8265
8294
  }
8266
8295
  }
8267
- var importMetaDir, DEFAULT_PROLOG_OUTPUT_MAX_BUFFER_BYTES, PROLOG_OUTPUT_OVERFLOW_ERROR = "Query exceeded bounded Prolog output capacity (ENOBUFS); narrow the operation or reduce stored entity size", INTERACTIVE_QUERY_FRAME_END = "__KIBI_QUERY_FRAME_END__", require2, KIBI_PACKAGE_VERSIONS, PrologProcessTerminatedError;
8296
+ var importMetaDir, DEFAULT_PROLOG_OUTPUT_MAX_BUFFER_BYTES, PROLOG_OUTPUT_OVERFLOW_ERROR = "Query exceeded bounded Prolog output capacity (ENOBUFS); narrow the operation or reduce stored entity size", INTERACTIVE_QUERY_FRAME_END = "__KIBI_QUERY_FRAME_END__", require3, PrologProcessTerminatedError;
8268
8297
  var init_prolog = __esm(() => {
8298
+ init_package_versions();
8269
8299
  init_performance_trace();
8270
8300
  init_error_terms();
8271
8301
  init_swipl_resolver();
8272
- importMetaDir = path4.dirname(fileURLToPath(import.meta.url));
8302
+ importMetaDir = path5.dirname(fileURLToPath2(import.meta.url));
8273
8303
  DEFAULT_PROLOG_OUTPUT_MAX_BUFFER_BYTES = 8 * 1024 * 1024;
8274
- require2 = createRequire2(import.meta.url);
8275
- KIBI_PACKAGE_VERSIONS = [
8276
- `kibi-cli@${packageVersion(path4.join(importMetaDir, "..", "package.json"))}`,
8277
- `kibi-core@${packageVersion(path4.join(importMetaDir, "..", "..", "core", "package.json"))}`,
8278
- `kibi-mcp@${packageVersion(path4.join(importMetaDir, "..", "..", "mcp", "package.json"))}`
8279
- ].join(",");
8304
+ require3 = createRequire3(import.meta.url);
8280
8305
  PrologProcessTerminatedError = class PrologProcessTerminatedError extends Error {
8281
8306
  code = "prolog_process_terminated";
8282
8307
  reason;
@@ -8290,7 +8315,7 @@ var init_prolog = __esm(() => {
8290
8315
 
8291
8316
  // ../cli/dist/prolog/store-lock.js
8292
8317
  import { existsSync as existsSync5, rmSync } from "node:fs";
8293
- import { readFileSync as readFileSync3 } from "node:fs";
8318
+ import { readFileSync as readFileSync4 } from "node:fs";
8294
8319
  import { dirname as dirname2, join as join2 } from "node:path";
8295
8320
  function currentBootId() {
8296
8321
  if (cachedBootId !== undefined)
@@ -8300,7 +8325,7 @@ function currentBootId() {
8300
8325
  return cachedBootId;
8301
8326
  }
8302
8327
  try {
8303
- const raw = readFileSync3("/proc/sys/kernel/random/boot_id", "utf8");
8328
+ const raw = readFileSync4("/proc/sys/kernel/random/boot_id", "utf8");
8304
8329
  cachedBootId = raw.trim();
8305
8330
  } catch {
8306
8331
  cachedBootId = null;
@@ -8342,7 +8367,7 @@ function readStoreLockOwner(storePath) {
8342
8367
  continue;
8343
8368
  let parsed;
8344
8369
  try {
8345
- parsed = JSON.parse(readFileSync3(journalPath, "utf8"));
8370
+ parsed = JSON.parse(readFileSync4(journalPath, "utf8"));
8346
8371
  } catch {
8347
8372
  continue;
8348
8373
  }
@@ -8419,19 +8444,19 @@ var init_store_lock = () => {};
8419
8444
 
8420
8445
  // ../cli/dist/utils/branch-store-locator.js
8421
8446
  import { createHash as createHash2 } from "node:crypto";
8422
- import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync4, readdirSync, statSync as statSync3, writeFileSync as writeFileSync2 } from "node:fs";
8423
- import path5 from "node:path";
8447
+ import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as readFileSync5, readdirSync, statSync as statSync3, writeFileSync as writeFileSync2 } from "node:fs";
8448
+ import path6 from "node:path";
8424
8449
  function branchStoreKey(branch) {
8425
8450
  return createHash2("sha256").update(branch, "utf8").digest("hex");
8426
8451
  }
8427
8452
  function branchStoresRoot(workspaceRoot) {
8428
- return path5.join(path5.resolve(workspaceRoot), ".kb", "branches");
8453
+ return path6.join(path6.resolve(workspaceRoot), ".kb", "branches");
8429
8454
  }
8430
8455
  function branchStorePath(workspaceRoot, branch) {
8431
- return path5.join(branchStoresRoot(workspaceRoot), branchStoreKey(branch));
8456
+ return path6.join(branchStoresRoot(workspaceRoot), branchStoreKey(branch));
8432
8457
  }
8433
8458
  function branchStoreManifestPath(storePath) {
8434
- return path5.join(storePath, "branch.json");
8459
+ return path6.join(storePath, "branch.json");
8435
8460
  }
8436
8461
  function expectedBranchStoreManifest(branch) {
8437
8462
  return {
@@ -8445,7 +8470,7 @@ function readBranchStoreManifest(storePath) {
8445
8470
  if (!existsSync6(manifestPath))
8446
8471
  return null;
8447
8472
  try {
8448
- const parsed = JSON.parse(readFileSync4(manifestPath, "utf8"));
8473
+ const parsed = JSON.parse(readFileSync5(manifestPath, "utf8"));
8449
8474
  if (parsed.version !== BRANCH_STORE_MANIFEST_VERSION || typeof parsed.branch !== "string" || typeof parsed.key !== "string") {
8450
8475
  return null;
8451
8476
  }
@@ -8461,7 +8486,7 @@ function readBranchStoreManifest(storePath) {
8461
8486
  function branchStoreManifestMatches(storePath, branch) {
8462
8487
  const manifest = readBranchStoreManifest(storePath);
8463
8488
  const expected = expectedBranchStoreManifest(branch);
8464
- return manifest !== null && manifest.version === expected.version && manifest.branch === expected.branch && manifest.key === expected.key && path5.basename(storePath) === expected.key;
8489
+ return manifest !== null && manifest.version === expected.version && manifest.branch === expected.branch && manifest.key === expected.key && path6.basename(storePath) === expected.key;
8465
8490
  }
8466
8491
  function ensureBranchStoreManifest(workspaceRoot, branch) {
8467
8492
  const storePath = branchStorePath(workspaceRoot, branch);
@@ -8485,7 +8510,7 @@ function ensureBranchStoreManifest(workspaceRoot, branch) {
8485
8510
  return storePath;
8486
8511
  }
8487
8512
  function legacyBranchStorePath(workspaceRoot, branch) {
8488
- return path5.join(branchStoresRoot(workspaceRoot), branch);
8513
+ return path6.join(branchStoresRoot(workspaceRoot), branch);
8489
8514
  }
8490
8515
  function isDirectory(pathname) {
8491
8516
  try {
@@ -8499,8 +8524,8 @@ var init_branch_store_locator = () => {};
8499
8524
 
8500
8525
  // ../cli/dist/utils/branch-resolver.js
8501
8526
  import { execFileSync as rawExecFileSync, execSync as rawExecSync } from "node:child_process";
8502
- import { copyFileSync, existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync5, readdirSync as readdirSync2, statSync as statSync4 } from "node:fs";
8503
- import * as path6 from "node:path";
8527
+ import { copyFileSync, existsSync as existsSync7, mkdirSync as mkdirSync3, readFileSync as readFileSync6, readdirSync as readdirSync2, statSync as statSync4 } from "node:fs";
8528
+ import * as path7 from "node:path";
8504
8529
  function unreadableMigrationJournalError(journalName) {
8505
8530
  return {
8506
8531
  error: `Unreadable branch migration journal '${journalName}' blocks attachment; recover it explicitly before continuing.`,
@@ -8514,7 +8539,7 @@ function _setBranchResolverDepsForTests(deps) {
8514
8539
  function isVolatileArtifact(fileName) {
8515
8540
  if (VOLATILE_ARTIFACTS.has(fileName))
8516
8541
  return true;
8517
- const ext = path6.extname(fileName).toLowerCase();
8542
+ const ext = path7.extname(fileName).toLowerCase();
8518
8543
  if (VOLATILE_EXTENSIONS.has(ext))
8519
8544
  return true;
8520
8545
  if (fileName.startsWith("journal-") && fileName.endsWith(".log"))
@@ -8683,13 +8708,13 @@ function resolveBranchAttachment(workspaceRoot = process.cwd()) {
8683
8708
  if ("error" in active)
8684
8709
  return active;
8685
8710
  const explicit = Boolean(getBranchOverride());
8686
- const migrationRoot = path6.join(path6.resolve(workspaceRoot), ".kb", "recovery", "branch-migrations");
8711
+ const migrationRoot = path7.join(path7.resolve(workspaceRoot), ".kb", "recovery", "branch-migrations");
8687
8712
  if (existsSync7(migrationRoot)) {
8688
8713
  for (const journalName of readdirSync2(migrationRoot)) {
8689
8714
  if (!journalName.endsWith(".json"))
8690
8715
  continue;
8691
8716
  try {
8692
- const journal = JSON.parse(readFileSync5(path6.join(migrationRoot, journalName), "utf8"));
8717
+ const journal = JSON.parse(readFileSync6(path7.join(migrationRoot, journalName), "utf8"));
8693
8718
  if (journal.state !== "committed" && journal.state !== "rolled_back") {
8694
8719
  const id = journalName.slice(0, -5);
8695
8720
  return {
@@ -8762,7 +8787,7 @@ function isValidBranchName(name) {
8762
8787
  const codePoint = character.codePointAt(0) ?? 0;
8763
8788
  return codePoint <= 32 || codePoint === 127;
8764
8789
  });
8765
- if (name.includes("..") || path6.isAbsolute(name) || name.startsWith("/")) {
8790
+ if (name.includes("..") || path7.isAbsolute(name) || name.startsWith("/")) {
8766
8791
  return false;
8767
8792
  }
8768
8793
  if (name.includes("//") || name.endsWith("/") || name.endsWith(".") || name.includes("\\") || name.startsWith("-") || name.includes("@{") || name.includes("..") || hasControlCharacter || /[~^:?*\[\]]/.test(name)) {
@@ -8795,8 +8820,8 @@ function copyDirectoryClean(sourceDir, targetDir) {
8795
8820
  if (isVolatileArtifact(entry)) {
8796
8821
  continue;
8797
8822
  }
8798
- const sourcePath = path6.join(sourceDir, entry);
8799
- const targetPath = path6.join(targetDir, entry);
8823
+ const sourcePath = path7.join(sourceDir, entry);
8824
+ const targetPath = path7.join(targetDir, entry);
8800
8825
  const stat = statSync4(sourcePath);
8801
8826
  if (stat.isDirectory()) {
8802
8827
  mkdirSync3(targetPath, { recursive: true });
@@ -8854,13 +8879,13 @@ var init_branch_resolver = __esm(() => {
8854
8879
 
8855
8880
  // ../cli/dist/utils/canonical-path.js
8856
8881
  import { lstatSync as lstatSync2, realpathSync as realpathSync2 } from "node:fs";
8857
- import path7 from "node:path";
8882
+ import path8 from "node:path";
8858
8883
  function canonicalFilesystemPath(candidate) {
8859
- let existing = path7.resolve(candidate);
8884
+ let existing = path8.resolve(candidate);
8860
8885
  const missing = [];
8861
8886
  for (;; ) {
8862
8887
  try {
8863
- return path7.resolve(realpathSync2.native(existing), ...missing);
8888
+ return path8.resolve(realpathSync2.native(existing), ...missing);
8864
8889
  } catch (error) {
8865
8890
  if (error.code !== "ENOENT")
8866
8891
  throw error;
@@ -8873,10 +8898,10 @@ function canonicalFilesystemPath(candidate) {
8873
8898
  }
8874
8899
  if (entry !== undefined)
8875
8900
  throw error;
8876
- const parent = path7.dirname(existing);
8901
+ const parent = path8.dirname(existing);
8877
8902
  if (parent === existing)
8878
8903
  throw error;
8879
- missing.unshift(path7.basename(existing));
8904
+ missing.unshift(path8.basename(existing));
8880
8905
  existing = parent;
8881
8906
  }
8882
8907
  }
@@ -8886,25 +8911,28 @@ var init_canonical_path = () => {};
8886
8911
  // ../cli/dist/engine.js
8887
8912
  import { spawn as spawn2 } from "node:child_process";
8888
8913
  import { createHash as createHash3, randomUUID } from "node:crypto";
8889
- import { chmodSync, closeSync as closeSync2, existsSync as existsSync8, fsyncSync, lstatSync as lstatSync3, mkdirSync as mkdirSync4, openSync as openSync2, readFileSync as readFileSync6, readdirSync as readdirSync3, realpathSync as realpathSync3, renameSync, rmSync as rmSync2, statSync as statSync5, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
8914
+ import { chmodSync, closeSync as closeSync2, existsSync as existsSync8, fsyncSync, lstatSync as lstatSync3, mkdirSync as mkdirSync4, openSync as openSync2, readFileSync as readFileSync7, readdirSync as readdirSync3, realpathSync as realpathSync3, renameSync, rmSync as rmSync2, statSync as statSync5, unlinkSync, writeFileSync as writeFileSync3 } from "node:fs";
8890
8915
  import * as net from "node:net";
8891
8916
  import * as os from "node:os";
8892
- import * as path8 from "node:path";
8893
- import { fileURLToPath as fileURLToPath2 } from "node:url";
8917
+ import * as path9 from "node:path";
8918
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
8919
+ function enginePackageVersions() {
8920
+ return kibiPackageVersions();
8921
+ }
8894
8922
  function engineSwiplIdentity() {
8895
8923
  return swiplIdentity(resolveSwipl());
8896
8924
  }
8897
8925
  function readJournalGeneration(branchPath) {
8898
- const currentPath = path8.join(branchPath, "CURRENT");
8926
+ const currentPath = path9.join(branchPath, "CURRENT");
8899
8927
  if (!existsSync8(currentPath))
8900
8928
  return "";
8901
- return readFileSync6(currentPath, "utf8").trim();
8929
+ return readFileSync7(currentPath, "utf8").trim();
8902
8930
  }
8903
8931
  function readEngineAttachmentIdentity(branchPath) {
8904
8932
  if (!existsSync8(branchPath))
8905
8933
  return null;
8906
8934
  const stats = statSync5(branchPath);
8907
- let resolved = path8.resolve(branchPath);
8935
+ let resolved = path9.resolve(branchPath);
8908
8936
  try {
8909
8937
  resolved = realpathSync3(branchPath);
8910
8938
  } catch {}
@@ -8978,15 +9006,15 @@ function parseFrames(buffer, onFrame) {
8978
9006
  return buffer.subarray(cursor);
8979
9007
  }
8980
9008
  function runtimeDirectory() {
8981
- const configured = process.env.KIBI_RUNTIME_DIR ?? process.env.XDG_RUNTIME_DIR ?? path8.join(os.tmpdir(), "kibi-runtime");
9009
+ const configured = process.env.KIBI_RUNTIME_DIR ?? process.env.XDG_RUNTIME_DIR ?? path9.join(os.tmpdir(), "kibi-runtime");
8982
9010
  if (process.platform === "win32") {
8983
9011
  for (const candidate of [
8984
9012
  configured,
8985
- path8.join(os.tmpdir(), "kibi-runtime")
9013
+ path9.join(os.tmpdir(), "kibi-runtime")
8986
9014
  ]) {
8987
9015
  try {
8988
9016
  mkdirSync4(candidate, { recursive: true, mode: 448 });
8989
- const probe = path8.join(candidate, `.kibi-write-${process.pid}`);
9017
+ const probe = path9.join(candidate, `.kibi-write-${process.pid}`);
8990
9018
  writeFileSync3(probe, "", { mode: 384 });
8991
9019
  unlinkSync(probe);
8992
9020
  return candidate;
@@ -9001,12 +9029,12 @@ function runtimeDirectory() {
9001
9029
  try {
9002
9030
  configuredIdentity = canonicalFilesystemPath(configured);
9003
9031
  } catch {
9004
- configuredIdentity = path8.resolve(configured);
9032
+ configuredIdentity = path9.resolve(configured);
9005
9033
  }
9006
9034
  const configuredKey = createHash3("sha256").update(configuredIdentity).digest("hex").slice(0, 32);
9007
9035
  const candidates = [
9008
9036
  configured,
9009
- path8.join("/tmp", `kb-${euid}-${configuredKey}`)
9037
+ path9.join("/tmp", `kb-${euid}-${configuredKey}`)
9010
9038
  ];
9011
9039
  const maximumBytes = process.platform === "linux" ? 107 : 103;
9012
9040
  const socketName = `kibi-${"0".repeat(32)}.sock`;
@@ -9024,9 +9052,9 @@ function runtimeDirectory() {
9024
9052
  if (!directory.isDirectory() || directory.uid !== euid || (directory.mode & 63) !== 0)
9025
9053
  continue;
9026
9054
  const canonical = canonicalFilesystemPath(candidate);
9027
- if (Buffer.byteLength(path8.join(canonical, socketName), "utf8") > maximumBytes)
9055
+ if (Buffer.byteLength(path9.join(canonical, socketName), "utf8") > maximumBytes)
9028
9056
  continue;
9029
- const probe = path8.join(canonical, `.kibi-write-${randomUUID()}`);
9057
+ const probe = path9.join(canonical, `.kibi-write-${randomUUID()}`);
9030
9058
  writeFileSync3(probe, "", { mode: 384, flag: "wx" });
9031
9059
  unlinkSync(probe);
9032
9060
  return canonical;
@@ -9047,7 +9075,7 @@ function fsyncPath(filePath) {
9047
9075
  }
9048
9076
  }
9049
9077
  function fsyncJournaledBranchStore(branchPath) {
9050
- const rdfRoot = path8.join(branchPath, "rdf");
9078
+ const rdfRoot = path9.join(branchPath, "rdf");
9051
9079
  const directories = [];
9052
9080
  const pending = existsSync8(rdfRoot) ? [rdfRoot] : [];
9053
9081
  while (pending.length > 0) {
@@ -9056,7 +9084,7 @@ function fsyncJournaledBranchStore(branchPath) {
9056
9084
  break;
9057
9085
  directories.push(directory);
9058
9086
  for (const entry of readdirSync3(directory, { withFileTypes: true })) {
9059
- const entryPath = path8.join(directory, entry.name);
9087
+ const entryPath = path9.join(directory, entry.name);
9060
9088
  if (entry.isDirectory())
9061
9089
  pending.push(entryPath);
9062
9090
  else if (entry.isFile() && entry.name !== "lock")
@@ -9064,7 +9092,7 @@ function fsyncJournaledBranchStore(branchPath) {
9064
9092
  }
9065
9093
  }
9066
9094
  for (const metadata of ["CURRENT", "storage.json", "kb.rdf"]) {
9067
- fsyncPath(path8.join(branchPath, metadata));
9095
+ fsyncPath(path9.join(branchPath, metadata));
9068
9096
  }
9069
9097
  if (process.platform !== "win32") {
9070
9098
  for (const directory of directories.reverse())
@@ -9078,18 +9106,18 @@ function engineSocketPath(workspaceRoot, branch) {
9078
9106
  if (process.platform === "win32") {
9079
9107
  return `\\\\.\\pipe\\kibi-${key}`;
9080
9108
  }
9081
- return path8.join(runtimeDirectory(), `kibi-${key}.sock`);
9109
+ return path9.join(runtimeDirectory(), `kibi-${key}.sock`);
9082
9110
  }
9083
9111
  function enginePidPath(workspaceRoot, branch) {
9084
9112
  const socket = engineSocketPath(workspaceRoot, branch);
9085
9113
  if (process.platform === "win32") {
9086
- return path8.join(runtimeDirectory(), `kibi-${createHash3("sha256").update(`${path8.resolve(workspaceRoot)}\x00${branch}`).digest("hex")}.pid`);
9114
+ return path9.join(runtimeDirectory(), `kibi-${createHash3("sha256").update(`${path9.resolve(workspaceRoot)}\x00${branch}`).digest("hex")}.pid`);
9087
9115
  }
9088
9116
  return `${socket}.pid`;
9089
9117
  }
9090
9118
  function engineStartLockPath(workspaceRoot, branch) {
9091
9119
  if (process.platform === "win32") {
9092
- return path8.join(runtimeDirectory(), `kibi-${createHash3("sha256").update(`${path8.resolve(workspaceRoot)}\x00${branch}`).digest("hex")}.start.lock`);
9120
+ return path9.join(runtimeDirectory(), `kibi-${createHash3("sha256").update(`${path9.resolve(workspaceRoot)}\x00${branch}`).digest("hex")}.start.lock`);
9093
9121
  }
9094
9122
  return `${engineSocketPath(workspaceRoot, branch)}.start.lock`;
9095
9123
  }
@@ -9098,7 +9126,7 @@ function enginePublicationLockPath(workspaceRoot, branch) {
9098
9126
  }
9099
9127
  function publicationLockOwner(lockPath) {
9100
9128
  try {
9101
- const [pidText, createdText] = readFileSync6(lockPath, "utf8").trim().split(":");
9129
+ const [pidText, createdText] = readFileSync7(lockPath, "utf8").trim().split(":");
9102
9130
  const pid = Number.parseInt(pidText ?? "", 10);
9103
9131
  const createdAt = Number.parseInt(createdText ?? "", 10);
9104
9132
  if (!Number.isInteger(pid) || pid <= 1 || !Number.isFinite(createdAt)) {
@@ -9146,7 +9174,7 @@ function publicationLockIsActive(lockPath) {
9146
9174
  }
9147
9175
  function acquireEnginePublicationLease(workspaceRoot, branch) {
9148
9176
  const lockPath = enginePublicationLockPath(workspaceRoot, branch);
9149
- mkdirSync4(path8.dirname(lockPath), { recursive: true, mode: 448 });
9177
+ mkdirSync4(path9.dirname(lockPath), { recursive: true, mode: 448 });
9150
9178
  let descriptor = null;
9151
9179
  try {
9152
9180
  descriptor = openSync2(lockPath, "wx", 384);
@@ -9200,7 +9228,7 @@ function tryAcquireStartLock(lockPath) {
9200
9228
  return descriptor;
9201
9229
  } catch {
9202
9230
  try {
9203
- const stamp = readFileSync6(lockPath, "utf8").trim().split(":");
9231
+ const stamp = readFileSync7(lockPath, "utf8").trim().split(":");
9204
9232
  const pid = Number.parseInt(stamp[0] ?? "", 10);
9205
9233
  const created = Number.parseInt(stamp[1] ?? "", 10);
9206
9234
  let age = 0;
@@ -9238,12 +9266,12 @@ function releaseStartLock(lockPath, descriptor) {
9238
9266
  } catch {}
9239
9267
  }
9240
9268
  function recoverStaleJournalLock(branchPath) {
9241
- const lockPath = path8.join(branchPath, "rdf", "lock");
9269
+ const lockPath = path9.join(branchPath, "rdf", "lock");
9242
9270
  if (!existsSync8(lockPath))
9243
9271
  return;
9244
9272
  let contents = "";
9245
9273
  try {
9246
- contents = readFileSync6(lockPath, "utf8");
9274
+ contents = readFileSync7(lockPath, "utf8");
9247
9275
  } catch {
9248
9276
  return;
9249
9277
  }
@@ -9263,11 +9291,11 @@ function recoverStaleJournalLock(branchPath) {
9263
9291
  }
9264
9292
  }
9265
9293
  function daemonEntry() {
9266
- const moduleDirectory = path8.dirname(fileURLToPath2(import.meta.url));
9294
+ const moduleDirectory = path9.dirname(fileURLToPath3(import.meta.url));
9267
9295
  const candidates = [
9268
- path8.join(moduleDirectory, "engine-daemon.js"),
9269
- path8.join(moduleDirectory, "..", "dist", "engine-daemon.js"),
9270
- path8.join(moduleDirectory, "..", "node_modules", "kibi-cli", "dist", "engine-daemon.js")
9296
+ path9.join(moduleDirectory, "engine-daemon.js"),
9297
+ path9.join(moduleDirectory, "..", "dist", "engine-daemon.js"),
9298
+ path9.join(moduleDirectory, "..", "node_modules", "kibi-cli", "dist", "engine-daemon.js")
9271
9299
  ];
9272
9300
  for (const candidate of candidates) {
9273
9301
  if (existsSync8(candidate))
@@ -9309,7 +9337,7 @@ async function connectWithRetry(socketPath, timeoutMs) {
9309
9337
  const errorPath = `${socketPath}.error`;
9310
9338
  if (existsSync8(errorPath)) {
9311
9339
  try {
9312
- const diagnostic = readFileSync6(errorPath, "utf8").trim();
9340
+ const diagnostic = readFileSync7(errorPath, "utf8").trim();
9313
9341
  if (diagnostic)
9314
9342
  throw new Error(diagnostic);
9315
9343
  } catch (error) {
@@ -9440,7 +9468,8 @@ class EngineClient {
9440
9468
  stdio: "ignore",
9441
9469
  env: {
9442
9470
  ...process.env,
9443
- KIBI_ENGINE_PROTOCOL: String(ENGINE_PROTOCOL_VERSION)
9471
+ KIBI_ENGINE_PROTOCOL: String(ENGINE_PROTOCOL_VERSION),
9472
+ KIBI_PACKAGE_VERSIONS: enginePackageVersions()
9444
9473
  }
9445
9474
  });
9446
9475
  await new Promise((resolve, reject) => {
@@ -9542,7 +9571,7 @@ class EngineClient {
9542
9571
  ...limits,
9543
9572
  id,
9544
9573
  protocolVersion: ENGINE_PROTOCOL_VERSION,
9545
- packageVersions: ENGINE_PACKAGE_VERSIONS,
9574
+ packageVersions: enginePackageVersions(),
9546
9575
  prologIdentity: engineSwiplIdentity(),
9547
9576
  workspaceRoot: this.workspaceRoot,
9548
9577
  branch: this.branch
@@ -9641,7 +9670,7 @@ class EngineClient {
9641
9670
  method: "cancel",
9642
9671
  cancelOf: requestId,
9643
9672
  protocolVersion: ENGINE_PROTOCOL_VERSION,
9644
- packageVersions: ENGINE_PACKAGE_VERSIONS,
9673
+ packageVersions: enginePackageVersions(),
9645
9674
  prologIdentity: engineSwiplIdentity(),
9646
9675
  workspaceRoot: this.workspaceRoot,
9647
9676
  branch: this.branch
@@ -9685,23 +9714,49 @@ class EngineClient {
9685
9714
  return null;
9686
9715
  return parseEngineAttachmentIdentity(status.bindings.JsonString);
9687
9716
  }
9688
- async daemonRuntimeMatches() {
9717
+ async daemonHandshake() {
9689
9718
  const reply = await this.request({
9690
9719
  method: "handshake"
9691
9720
  });
9692
- return reply?.prologIdentity === engineSwiplIdentity();
9721
+ return {
9722
+ prologIdentity: typeof reply?.prologIdentity === "string" ? reply.prologIdentity : null,
9723
+ packageVersions: typeof reply?.packageVersions === "string" ? reply.packageVersions : null
9724
+ };
9725
+ }
9726
+ async inspectLiveDaemon() {
9727
+ const wasConnected = this.isRunning();
9728
+ if (!wasConnected)
9729
+ await this.connect(false);
9730
+ if (!this.isRunning())
9731
+ return null;
9732
+ try {
9733
+ return await this.daemonHandshake();
9734
+ } finally {
9735
+ if (!wasConnected)
9736
+ await this.terminate();
9737
+ }
9738
+ }
9739
+ async daemonRuntimeMismatch() {
9740
+ const daemon = await this.daemonHandshake();
9741
+ const packageVersions = enginePackageVersions();
9742
+ if (daemon.packageVersions !== packageVersions)
9743
+ return `Kibi engine is running other package versions (${daemon.packageVersions ?? "not reported"}) than this client (${packageVersions})`;
9744
+ if (daemon.prologIdentity !== engineSwiplIdentity())
9745
+ return `Kibi engine is running a different SWI-Prolog than this client resolved (${engineSwiplIdentity()})`;
9746
+ return null;
9693
9747
  }
9694
9748
  async reconcileRuntime() {
9695
9749
  if (this.replacingStaleDaemon || this.socket === null)
9696
9750
  return;
9697
- if (await this.daemonRuntimeMatches())
9751
+ if (await this.daemonRuntimeMismatch() === null)
9698
9752
  return;
9699
9753
  this.replacingStaleDaemon = true;
9700
9754
  try {
9701
9755
  await this.shutdownConnectedDaemon();
9702
9756
  await this.connect(true);
9703
- if (!await this.daemonRuntimeMatches()) {
9704
- throw new Error(`Kibi engine is running a different SWI-Prolog than this client resolved (${engineSwiplIdentity()}); run 'kibi engine stop' and retry`);
9757
+ const mismatch = await this.daemonRuntimeMismatch();
9758
+ if (mismatch !== null) {
9759
+ throw new Error(`${mismatch} after replacing it; run 'kibi engine stop' and retry`);
9705
9760
  }
9706
9761
  } finally {
9707
9762
  this.replacingStaleDaemon = false;
@@ -9765,7 +9820,7 @@ class EngineClient {
9765
9820
  getPid() {
9766
9821
  const pidPath = enginePidPath(this.workspaceRoot, this.branch);
9767
9822
  try {
9768
- return Number.parseInt(readFileSync6(pidPath, "utf8").trim(), 10) || 0;
9823
+ return Number.parseInt(readFileSync7(pidPath, "utf8").trim(), 10) || 0;
9769
9824
  } catch {
9770
9825
  return 0;
9771
9826
  }
@@ -9796,12 +9851,12 @@ class EngineClient {
9796
9851
  }
9797
9852
  async function ensureJournaledBranchStoreAsync(branchPath) {
9798
9853
  mkdirSync4(branchPath, { recursive: true });
9799
- const markerPath = path8.join(branchPath, "storage.json");
9800
- const marker = existsSync8(markerPath) ? readFileSync6(markerPath, "utf8") : "";
9854
+ const markerPath = path9.join(branchPath, "storage.json");
9855
+ const marker = existsSync8(markerPath) ? readFileSync7(markerPath, "utf8") : "";
9801
9856
  if (marker.includes("kibi.rdf-journal.v1")) {
9802
- const rdfDirectory = path8.join(branchPath, "rdf");
9803
- const currentPath = path8.join(branchPath, "CURRENT");
9804
- const sentinelPath = path8.join(branchPath, "kb.rdf");
9857
+ const rdfDirectory = path9.join(branchPath, "rdf");
9858
+ const currentPath = path9.join(branchPath, "CURRENT");
9859
+ const sentinelPath = path9.join(branchPath, "kb.rdf");
9805
9860
  if (!existsSync8(rdfDirectory) || !existsSync8(currentPath)) {
9806
9861
  recoverInterruptedGeneration(branchPath);
9807
9862
  if (existsSync8(rdfDirectory) && existsSync8(currentPath)) {
@@ -9813,9 +9868,9 @@ async function ensureJournaledBranchStoreAsync(branchPath) {
9813
9868
  }
9814
9869
  return;
9815
9870
  }
9816
- const legacyRdf = path8.join(branchPath, "kb.rdf");
9817
- const legacyAudit = path8.join(branchPath, "audit.log");
9818
- const legacyContents = existsSync8(legacyRdf) ? readFileSync6(legacyRdf, "utf8") : "";
9871
+ const legacyRdf = path9.join(branchPath, "kb.rdf");
9872
+ const legacyAudit = path9.join(branchPath, "audit.log");
9873
+ const legacyContents = existsSync8(legacyRdf) ? readFileSync7(legacyRdf, "utf8") : "";
9819
9874
  if (existsSync8(legacyAudit) || existsSync8(legacyRdf) && !legacyContents.includes("kibi.rdf-journal.v1")) {
9820
9875
  rmSync2(rdfDirectory, { recursive: true, force: true });
9821
9876
  rmSync2(currentPath, { force: true });
@@ -9833,29 +9888,29 @@ async function ensureJournaledBranchStoreAsync(branchPath) {
9833
9888
  return;
9834
9889
  }
9835
9890
  }
9836
- const legacyRdf = path8.join(branchPath, "kb.rdf");
9837
- const legacyAudit = path8.join(branchPath, "audit.log");
9891
+ const legacyRdf = path9.join(branchPath, "kb.rdf");
9892
+ const legacyAudit = path9.join(branchPath, "audit.log");
9838
9893
  if (!existsSync8(legacyRdf) && !existsSync8(legacyAudit)) {
9839
- mkdirSync4(path8.join(branchPath, "rdf"), { recursive: true });
9894
+ mkdirSync4(path9.join(branchPath, "rdf"), { recursive: true });
9840
9895
  writeFileSync3(markerPath, `{"format":"kibi.rdf-journal.v1","schemaVersion":1}
9841
9896
  `, { mode: 384 });
9842
- writeFileSync3(path8.join(branchPath, "CURRENT"), `generation-1:0
9897
+ writeFileSync3(path9.join(branchPath, "CURRENT"), `generation-1:0
9843
9898
  `, {
9844
9899
  mode: 384
9845
9900
  });
9846
- writeFileSync3(path8.join(branchPath, "kb.rdf"), `KIBI_STORAGE_FORMAT=kibi.rdf-journal.v1
9901
+ writeFileSync3(path9.join(branchPath, "kb.rdf"), `KIBI_STORAGE_FORMAT=kibi.rdf-journal.v1
9847
9902
  `, { mode: 384 });
9848
9903
  return;
9849
9904
  }
9850
9905
  if (existsSync8(legacyRdf)) {
9851
- const legacyContents = readFileSync6(legacyRdf, "utf8");
9906
+ const legacyContents = readFileSync7(legacyRdf, "utf8");
9852
9907
  if (!/<rdf:RDF(?:\s|>)/.test(legacyContents)) {
9853
9908
  throw new Error(`Legacy Kibi store is corrupt at ${legacyRdf}: expected RDF/XML root`);
9854
9909
  }
9855
9910
  }
9856
- const parent = path8.dirname(branchPath);
9857
- const migrationKey = createHash3("sha256").update(path8.resolve(branchPath)).digest("hex").slice(0, 16);
9858
- const staging = path8.join(parent, `.${migrationKey}.migration.${process.pid}.${Date.now()}`);
9911
+ const parent = path9.dirname(branchPath);
9912
+ const migrationKey = createHash3("sha256").update(path9.resolve(branchPath)).digest("hex").slice(0, 16);
9913
+ const staging = path9.join(parent, `.${migrationKey}.migration.${process.pid}.${Date.now()}`);
9859
9914
  mkdirSync4(staging, { recursive: true, mode: 448 });
9860
9915
  const testOneShot = false;
9861
9916
  const migrator = new PrologProcess({
@@ -9883,35 +9938,35 @@ async function ensureJournaledBranchStoreAsync(branchPath) {
9883
9938
  await migrator.terminate();
9884
9939
  }
9885
9940
  for (const file of ["rdf", "storage.json", "CURRENT"]) {
9886
- const source = path8.join(staging, file);
9941
+ const source = path9.join(staging, file);
9887
9942
  if (!existsSync8(source))
9888
9943
  continue;
9889
- const target = path8.join(branchPath, file);
9944
+ const target = path9.join(branchPath, file);
9890
9945
  if (existsSync8(target))
9891
9946
  rmSync2(target, { recursive: true, force: true });
9892
9947
  renameSync(source, target);
9893
9948
  }
9894
9949
  archiveLegacyFiles(branchPath);
9895
- writeFileSync3(path8.join(branchPath, "kb.rdf"), `KIBI_STORAGE_FORMAT=kibi.rdf-journal.v1
9950
+ writeFileSync3(path9.join(branchPath, "kb.rdf"), `KIBI_STORAGE_FORMAT=kibi.rdf-journal.v1
9896
9951
  `, { mode: 384 });
9897
9952
  fsyncJournaledBranchStore(branchPath);
9898
9953
  rmSync2(staging, { recursive: true, force: true });
9899
9954
  }
9900
9955
  function archiveLegacyFiles(branchPath) {
9901
- const legacyDir = path8.join(branchPath, "legacy");
9956
+ const legacyDir = path9.join(branchPath, "legacy");
9902
9957
  mkdirSync4(legacyDir, { recursive: true, mode: 448 });
9903
9958
  for (const file of ["kb.rdf", "audit.log"]) {
9904
- const source = path8.join(branchPath, file);
9959
+ const source = path9.join(branchPath, file);
9905
9960
  if (!existsSync8(source))
9906
9961
  continue;
9907
9962
  if (file === "kb.rdf") {
9908
- const contents = readFileSync6(source, "utf8");
9963
+ const contents = readFileSync7(source, "utf8");
9909
9964
  if (contents.includes("kibi.rdf-journal.v1"))
9910
9965
  continue;
9911
9966
  }
9912
- const destination = path8.join(legacyDir, file);
9967
+ const destination = path9.join(legacyDir, file);
9913
9968
  if (existsSync8(destination)) {
9914
- renameSync(source, path8.join(legacyDir, `${file}.recovery.${Date.now()}`));
9969
+ renameSync(source, path9.join(legacyDir, `${file}.recovery.${Date.now()}`));
9915
9970
  } else {
9916
9971
  renameSync(source, destination);
9917
9972
  }
@@ -9927,12 +9982,12 @@ function recoverInterruptedGeneration(branchPath) {
9927
9982
  const newest = (prefix) => {
9928
9983
  const candidates = entries.filter((entry) => entry.startsWith(prefix)).sort().reverse();
9929
9984
  const candidate = candidates[0];
9930
- return candidate === undefined ? null : path8.join(branchPath, candidate);
9985
+ return candidate === undefined ? null : path9.join(branchPath, candidate);
9931
9986
  };
9932
9987
  const oldRdf = newest("rdf.old.");
9933
9988
  const oldCurrent = newest("CURRENT.old.");
9934
- const rdfPath = path8.join(branchPath, "rdf");
9935
- const currentPath = path8.join(branchPath, "CURRENT");
9989
+ const rdfPath = path9.join(branchPath, "rdf");
9990
+ const currentPath = path9.join(branchPath, "CURRENT");
9936
9991
  if ((!existsSync8(rdfPath) || !existsSync8(currentPath)) && oldRdf && oldCurrent) {
9937
9992
  try {
9938
9993
  if (existsSync8(rdfPath))
@@ -9958,6 +10013,7 @@ function recoverInterruptedGeneration(branchPath) {
9958
10013
  var READ_LIMITED_METHODS, ENGINE_PROTOCOL_VERSION = 1, ENGINE_IDLE_TIMEOUT_MS, ENGINE_PACKAGE_VERSIONS, ENGINE_QUERY_CACHE_MAX_RESULT_BYTES, ENGINE_PUBLICATION_LOCK_STALE_MS = 5000;
9959
10014
  var init_engine = __esm(() => {
9960
10015
  init_engine_limits();
10016
+ init_package_versions();
9961
10017
  init_performance_trace();
9962
10018
  init_prolog();
9963
10019
  init_store_lock();
@@ -9974,7 +10030,7 @@ var init_engine = __esm(() => {
9974
10030
  "search"
9975
10031
  ]);
9976
10032
  ENGINE_IDLE_TIMEOUT_MS = 10 * 60 * 1000;
9977
- ENGINE_PACKAGE_VERSIONS = process.env.KIBI_PACKAGE_VERSIONS ?? "unknown";
10033
+ ENGINE_PACKAGE_VERSIONS = kibiPackageVersions();
9978
10034
  ENGINE_QUERY_CACHE_MAX_RESULT_BYTES = 8 * 1024 * 1024;
9979
10035
  });
9980
10036
 
@@ -10237,7 +10293,7 @@ var init_entity_body_context = __esm(() => {
10237
10293
 
10238
10294
  // ../cli/dist/search-ranking.js
10239
10295
  import fs from "node:fs/promises";
10240
- import path9 from "node:path";
10296
+ import path10 from "node:path";
10241
10297
  async function rankEntities(entities, query, workspaceRoot) {
10242
10298
  const queryContext = buildSearchQueryContext(query);
10243
10299
  if (!queryContext.rawTrimmedQuery || queryContext.signalTokens.length === 0) {
@@ -10341,9 +10397,9 @@ async function loadMarkdownBody(source, workspaceRoot) {
10341
10397
  if (!normalizedSource.endsWith(".md")) {
10342
10398
  return null;
10343
10399
  }
10344
- const resolved = path9.resolve(path9.isAbsolute(normalizedSource) ? normalizedSource : path9.join(workspaceRoot, normalizedSource));
10345
- const normalizedRoot = path9.resolve(workspaceRoot);
10346
- if (!resolved.startsWith(normalizedRoot + path9.sep)) {
10400
+ const resolved = path10.resolve(path10.isAbsolute(normalizedSource) ? normalizedSource : path10.join(workspaceRoot, normalizedSource));
10401
+ const normalizedRoot = path10.resolve(workspaceRoot);
10402
+ if (!resolved.startsWith(normalizedRoot + path10.sep)) {
10347
10403
  return null;
10348
10404
  }
10349
10405
  try {
@@ -10469,7 +10525,7 @@ var init_search_ranking = __esm(() => {
10469
10525
  });
10470
10526
 
10471
10527
  // ../cli/dist/intent-search.js
10472
- import path10 from "node:path";
10528
+ import path11 from "node:path";
10473
10529
  function normalize(value) {
10474
10530
  return value.trim().toLowerCase().replace(/[-_]+/g, " ").replace(/[^a-z0-9\s]+/g, " ").split(/\s+/).filter(Boolean).map((token) => token.length > 4 && token.endsWith("s") && !token.endsWith("ss") ? token.slice(0, -1) : token).map(stem).join(" ");
10475
10531
  }
@@ -10841,7 +10897,7 @@ function validateIntentSearchInput(input) {
10841
10897
  throw new Error("Search execution failed: minScore must be between 0 and 1");
10842
10898
  }
10843
10899
  for (const location of input.sourceLocations ?? []) {
10844
- if (!location.path.trim() || path10.isAbsolute(location.path) || location.path.split("/").includes("..")) {
10900
+ if (!location.path.trim() || path11.isAbsolute(location.path) || location.path.split("/").includes("..")) {
10845
10901
  throw new Error("Search execution failed: sourceLocations.path must be workspace-relative");
10846
10902
  }
10847
10903
  if (location.line !== undefined && (!Number.isInteger(location.line) || location.line < 1)) {
@@ -11089,8 +11145,8 @@ var LATEST_KB_SCHEMA_VERSION = 8;
11089
11145
 
11090
11146
  // ../cli/dist/utils/kb-manifest.js
11091
11147
  import { createHash as createHash4 } from "node:crypto";
11092
- import { existsSync as existsSync9, mkdirSync as mkdirSync5, readFileSync as readFileSync7, renameSync as renameSync2, writeFileSync as writeFileSync4 } from "node:fs";
11093
- import * as path11 from "node:path";
11148
+ import { existsSync as existsSync9, mkdirSync as mkdirSync5, readFileSync as readFileSync8, renameSync as renameSync2, writeFileSync as writeFileSync4 } from "node:fs";
11149
+ import * as path12 from "node:path";
11094
11150
  function defaultKbManifest() {
11095
11151
  return {
11096
11152
  manifestVersion: KB_MANIFEST_VERSION,
@@ -11099,7 +11155,7 @@ function defaultKbManifest() {
11099
11155
  };
11100
11156
  }
11101
11157
  function manifestPathFor(workspaceRoot) {
11102
- return path11.join(workspaceRoot, KB_PATHS.manifest);
11158
+ return path12.join(workspaceRoot, KB_PATHS.manifest);
11103
11159
  }
11104
11160
  function isRecord(value) {
11105
11161
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -11143,7 +11199,7 @@ function readKbManifestStatus(workspaceRoot) {
11143
11199
  }
11144
11200
  let contents;
11145
11201
  try {
11146
- contents = readFileSync7(manifestPath, "utf8");
11202
+ contents = readFileSync8(manifestPath, "utf8");
11147
11203
  } catch {
11148
11204
  return {
11149
11205
  state: "invalid",
@@ -11189,7 +11245,7 @@ function readKbManifest(workspaceRoot) {
11189
11245
  return status.state === "ok" ? status.manifest : null;
11190
11246
  }
11191
11247
  function writeAtomically(filePath, content) {
11192
- mkdirSync5(path11.dirname(filePath), { recursive: true });
11248
+ mkdirSync5(path12.dirname(filePath), { recursive: true });
11193
11249
  const tempPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
11194
11250
  writeFileSync4(tempPath, content, "utf8");
11195
11251
  renameSync2(tempPath, filePath);
@@ -11206,7 +11262,7 @@ var init_kb_manifest = __esm(() => {
11206
11262
  });
11207
11263
 
11208
11264
  // ../cli/dist/operations/bootstrap/activation.js
11209
- import path12 from "node:path";
11265
+ import path13 from "node:path";
11210
11266
  function missingManifestActivation(vendored, projectSignal) {
11211
11267
  return activationFor(vendored && !projectSignal ? "vendored_only" : "root_uninitialized");
11212
11268
  }
@@ -11294,21 +11350,21 @@ function sourceCoverageState(files) {
11294
11350
  async function classifyActivation(context, files = []) {
11295
11351
  const sourceFiles = Array.isArray(files) ? files : [];
11296
11352
  const normalizedFiles = sourceFiles.map((file) => {
11297
- const relative = path12.isAbsolute(file) ? path12.relative(context.workspaceRoot, file) : file;
11353
+ const relative = path13.isAbsolute(file) ? path13.relative(context.workspaceRoot, file) : file;
11298
11354
  return relative.replaceAll("\\", "/");
11299
11355
  });
11300
11356
  const manifestStatus = readKbManifestStatus(context.workspaceRoot);
11301
11357
  if (manifestStatus.state === "missing") {
11302
11358
  const vendored = normalizedFiles.some((file) => file.startsWith("kibi/"));
11303
11359
  const projectSignalFromFiles = normalizedFiles.some((file) => !file.startsWith("kibi/") && /^(README\.md|package\.json|src\/|app\/|packages\/|tests\/)/.test(file));
11304
- const projectSignalFromDirectories = await Promise.all(["README.md", "package.json", "src", "app", "packages", "tests"].map((target) => exists(context, path12.resolve(context.workspaceRoot, target))));
11360
+ const projectSignalFromDirectories = await Promise.all(["README.md", "package.json", "src", "app", "packages", "tests"].map((target) => exists(context, path13.resolve(context.workspaceRoot, target))));
11305
11361
  const projectSignal = projectSignalFromFiles || projectSignalFromDirectories.some(Boolean);
11306
11362
  return missingManifestActivation(vendored, projectSignal);
11307
11363
  }
11308
11364
  if (manifestStatus.state !== "ok")
11309
11365
  return activationFor("root_partial");
11310
11366
  const targets = [...Object.values(KB_PATHS.lanes), KB_PATHS.symbolsManifest];
11311
- const resolved = await Promise.all(targets.map((target) => exists(context, path12.resolve(context.workspaceRoot, target))));
11367
+ const resolved = await Promise.all(targets.map((target) => exists(context, path13.resolve(context.workspaceRoot, target))));
11312
11368
  if (resolved.some((value) => !value))
11313
11369
  return activationFor("root_partial");
11314
11370
  if (!context.prolog)
@@ -11328,10 +11384,10 @@ var init_activation = __esm(() => {
11328
11384
  });
11329
11385
 
11330
11386
  // ../cli/dist/public/operations/prolog-json.js
11331
- import path13 from "node:path";
11387
+ import path14 from "node:path";
11332
11388
  function resolveCoreModulePath(fileName) {
11333
11389
  const genericOverride = getKbPlPathOverride();
11334
- return path13.join(path13.dirname(genericOverride ?? resolveKbPlPath()), fileName);
11390
+ return path14.join(path14.dirname(genericOverride ?? resolveKbPlPath()), fileName);
11335
11391
  }
11336
11392
  async function runOperationJsonQuery(prolog, fileName, goal, errorLabel, signal) {
11337
11393
  const modulePath = escapeAtom(resolveCoreModulePath(fileName).replaceAll("\\", "/"));
@@ -12128,8 +12184,8 @@ var init_search_answer = __esm(() => {
12128
12184
  });
12129
12185
 
12130
12186
  // ../cli/dist/utils/branch-store.js
12131
- import { existsSync as existsSync10, readFileSync as readFileSync8, statSync as statSync6 } from "node:fs";
12132
- import * as path14 from "node:path";
12187
+ import { existsSync as existsSync10, readFileSync as readFileSync9, statSync as statSync6 } from "node:fs";
12188
+ import * as path15 from "node:path";
12133
12189
  function inspectBranchStore(workspaceRoot, branch) {
12134
12190
  const storePath = branchStorePath(workspaceRoot, branch);
12135
12191
  if (!existsSync10(storePath)) {
@@ -12170,10 +12226,10 @@ function inspectBranchStore(workspaceRoot, branch) {
12170
12226
  recoveryRequired: true
12171
12227
  };
12172
12228
  }
12173
- const markerPath = path14.join(storePath, "storage.json");
12174
- const rdfPath = path14.join(storePath, "rdf");
12175
- const currentPath = path14.join(storePath, "CURRENT");
12176
- const legacyPath = path14.join(storePath, "kb.rdf");
12229
+ const markerPath = path15.join(storePath, "storage.json");
12230
+ const rdfPath = path15.join(storePath, "rdf");
12231
+ const currentPath = path15.join(storePath, "CURRENT");
12232
+ const legacyPath = path15.join(storePath, "kb.rdf");
12177
12233
  if (existsSync10(markerPath)) {
12178
12234
  if (!existsSync10(rdfPath) || !statSync6(rdfPath).isDirectory()) {
12179
12235
  return {
@@ -12193,7 +12249,7 @@ function inspectBranchStore(workspaceRoot, branch) {
12193
12249
  recoveryRequired: true
12194
12250
  };
12195
12251
  }
12196
- const current = readFileSync8(currentPath, "utf8").trim();
12252
+ const current = readFileSync9(currentPath, "utf8").trim();
12197
12253
  if (!/^generation-[^:\s]+:\d+$/.test(current)) {
12198
12254
  return {
12199
12255
  state: "unreadable",
@@ -12206,7 +12262,7 @@ function inspectBranchStore(workspaceRoot, branch) {
12206
12262
  return { state: "healthy", path: storePath, recoveryRequired: false };
12207
12263
  }
12208
12264
  if (existsSync10(legacyPath)) {
12209
- const legacy = readFileSync8(legacyPath, "utf8");
12265
+ const legacy = readFileSync9(legacyPath, "utf8");
12210
12266
  if (!/<rdf:RDF(?:\s|>)/.test(legacy)) {
12211
12267
  return {
12212
12268
  state: "unreadable",
@@ -12270,8 +12326,8 @@ var init_branch_store = __esm(() => {
12270
12326
  });
12271
12327
 
12272
12328
  // ../cli/dist/utils/config.js
12273
- import { existsSync as existsSync11, readFileSync as readFileSync9 } from "node:fs";
12274
- import * as path15 from "node:path";
12329
+ import { existsSync as existsSync11, readFileSync as readFileSync10 } from "node:fs";
12330
+ import * as path16 from "node:path";
12275
12331
  function loadEntityPaths(_cwd = process.cwd()) {
12276
12332
  return CANONICAL_ENTITY_PATHS;
12277
12333
  }
@@ -12283,15 +12339,15 @@ function pickLegacyPathValue(paths, key) {
12283
12339
  return typeof value === "string" ? value : undefined;
12284
12340
  }
12285
12341
  function legacyConfigExists(cwd) {
12286
- return existsSync11(path15.join(cwd, ".kb", "config.json"));
12342
+ return existsSync11(path16.join(cwd, ".kb", "config.json"));
12287
12343
  }
12288
12344
  function readLegacyKbConfig(cwd) {
12289
- const configPath = path15.join(cwd, ".kb", "config.json");
12345
+ const configPath = path16.join(cwd, ".kb", "config.json");
12290
12346
  if (!existsSync11(configPath))
12291
12347
  return { kind: "none" };
12292
12348
  let raw;
12293
12349
  try {
12294
- raw = readFileSync9(configPath, "utf8");
12350
+ raw = readFileSync10(configPath, "utf8");
12295
12351
  } catch (error) {
12296
12352
  return {
12297
12353
  kind: "malformed",
@@ -12852,8 +12908,8 @@ __export(exports_migration_plan, {
12852
12908
  withoutActionCodes: () => withoutActionCodes
12853
12909
  });
12854
12910
  import { createHash as createHash5 } from "node:crypto";
12855
- import { existsSync as existsSync12, readFileSync as readFileSync10 } from "node:fs";
12856
- import * as path16 from "node:path";
12911
+ import { existsSync as existsSync12, readFileSync as readFileSync11 } from "node:fs";
12912
+ import * as path17 from "node:path";
12857
12913
  function isRecord4(value) {
12858
12914
  return value !== null && typeof value === "object" && !Array.isArray(value);
12859
12915
  }
@@ -13192,11 +13248,11 @@ function readMigrationConfigStatus(workspaceRoot) {
13192
13248
  };
13193
13249
  }
13194
13250
  function readLegacySchemaVersion(workspaceRoot) {
13195
- const legacyPath = path16.join(workspaceRoot, ".kb", "config.json");
13251
+ const legacyPath = path17.join(workspaceRoot, ".kb", "config.json");
13196
13252
  if (!existsSync12(legacyPath))
13197
13253
  return null;
13198
13254
  try {
13199
- const parsed = JSON.parse(readFileSync10(legacyPath, "utf8"));
13255
+ const parsed = JSON.parse(readFileSync11(legacyPath, "utf8"));
13200
13256
  return parsed.schemaVersion ?? null;
13201
13257
  } catch {
13202
13258
  return "";
@@ -13385,7 +13441,7 @@ async function readWorkspaceSnapshot(context) {
13385
13441
  }
13386
13442
 
13387
13443
  // ../cli/dist/public/operations/discovery-executors.js
13388
- import path17 from "node:path";
13444
+ import path18 from "node:path";
13389
13445
  function requireProlog(context) {
13390
13446
  if (!context.prolog) {
13391
13447
  throw new Error("Discovery operation requires a Prolog context");
@@ -13635,16 +13691,16 @@ async function executeStatus(_input, context) {
13635
13691
  const bootstrapActivation = await classifyActivation(context, bootstrapSourceFiles);
13636
13692
  const incompleteApplications = [];
13637
13693
  if (context.fs?.glob) {
13638
- const recoveryRoot = path17.join(context.workspaceRoot, ".kb", "recovery");
13694
+ const recoveryRoot = path18.join(context.workspaceRoot, ".kb", "recovery");
13639
13695
  const journals = await context.fs.glob(["bootstrap-*.json"], {
13640
13696
  cwd: recoveryRoot
13641
13697
  });
13642
13698
  for (const journalPath of journals) {
13643
13699
  try {
13644
- const journal = JSON.parse(await context.fs.readFile(path17.resolve(recoveryRoot, journalPath)));
13700
+ const journal = JSON.parse(await context.fs.readFile(path18.resolve(recoveryRoot, journalPath)));
13645
13701
  if (journal.kind === "bootstrap" && ["rejected", "repair_required", "applying"].includes(journal.state))
13646
13702
  incompleteApplications.push({
13647
- journalId: path17.basename(journalPath, ".json"),
13703
+ journalId: path18.basename(journalPath, ".json"),
13648
13704
  state: journal.state,
13649
13705
  appliedActions: (journal.results ?? []).filter((row) => row.outcome === "applied").length,
13650
13706
  failedActions: (journal.results ?? []).filter((row) => row.outcome === "failed"),
@@ -13652,7 +13708,7 @@ async function executeStatus(_input, context) {
13652
13708
  });
13653
13709
  } catch (error) {
13654
13710
  incompleteApplications.push({
13655
- journalId: path17.basename(journalPath, ".json"),
13711
+ journalId: path18.basename(journalPath, ".json"),
13656
13712
  state: "unreadable",
13657
13713
  detail: error instanceof Error ? error.message : String(error)
13658
13714
  });
@@ -14317,12 +14373,12 @@ var init_entity_origin = __esm(() => {
14317
14373
  });
14318
14374
 
14319
14375
  // ../cli/dist/utils/manifest-paths.js
14320
- import * as path18 from "node:path";
14376
+ import * as path19 from "node:path";
14321
14377
  function resolveSymbolsManifestPaths(workspaceRoot) {
14322
- const symbolsPath = path18.join(workspaceRoot, CANONICAL_ENTITY_PATHS.symbols);
14378
+ const symbolsPath = path19.join(workspaceRoot, CANONICAL_ENTITY_PATHS.symbols);
14323
14379
  return {
14324
14380
  symbolsPath,
14325
- coordinatesPath: path18.join(workspaceRoot, DEFAULT_COORDINATES_PATH)
14381
+ coordinatesPath: path19.join(workspaceRoot, DEFAULT_COORDINATES_PATH)
14326
14382
  };
14327
14383
  }
14328
14384
  var DEFAULT_SYMBOLS_PATH, DEFAULT_COORDINATES_PATH;
@@ -14333,22 +14389,22 @@ var init_manifest_paths = __esm(() => {
14333
14389
  });
14334
14390
 
14335
14391
  // ../cli/dist/utils/repo-relative-path.js
14336
- import path19 from "node:path";
14392
+ import path20 from "node:path";
14337
14393
  function normalizeRepoRelativePath(workspaceRoot, candidate) {
14338
14394
  if (candidate.trim() === "")
14339
14395
  return null;
14340
14396
  let slashed = candidate.replaceAll("\\", "/");
14341
14397
  const foreignAbsolute = /^[A-Za-z]:\//.test(slashed) || slashed.startsWith("//");
14342
14398
  if (slashed.startsWith("/") || foreignAbsolute) {
14343
- if (foreignAbsolute && path19.sep === "/")
14399
+ if (foreignAbsolute && path20.sep === "/")
14344
14400
  return null;
14345
- const root = path19.resolve(workspaceRoot);
14346
- const relative = path19.relative(root, path19.resolve(candidate));
14347
- if (relative === "" || path19.isAbsolute(relative))
14401
+ const root = path20.resolve(workspaceRoot);
14402
+ const relative = path20.relative(root, path20.resolve(candidate));
14403
+ if (relative === "" || path20.isAbsolute(relative))
14348
14404
  return null;
14349
14405
  slashed = relative.replaceAll("\\", "/");
14350
14406
  }
14351
- const normalized = path19.posix.normalize(slashed).replace(/\/+$/, "");
14407
+ const normalized = path20.posix.normalize(slashed).replace(/\/+$/, "");
14352
14408
  if (normalized === "" || normalized === "." || normalized === ".." || normalized.startsWith("../")) {
14353
14409
  return null;
14354
14410
  }
@@ -14358,8 +14414,8 @@ var init_repo_relative_path = () => {};
14358
14414
 
14359
14415
  // ../cli/dist/extractors/symbol-coordinates.js
14360
14416
  import { createHash as createHash8 } from "node:crypto";
14361
- import { existsSync as existsSync13, readFileSync as readFileSync11 } from "node:fs";
14362
- import * as path20 from "node:path";
14417
+ import { existsSync as existsSync13, readFileSync as readFileSync12 } from "node:fs";
14418
+ import * as path21 from "node:path";
14363
14419
  function isRecord7(value) {
14364
14420
  return typeof value === "object" && value !== null && !Array.isArray(value);
14365
14421
  }
@@ -14570,11 +14626,11 @@ function manifestSourceFile(record) {
14570
14626
  return;
14571
14627
  }
14572
14628
  function defaultResolveSourceText(sourceFile) {
14573
- const absolute = path20.isAbsolute(sourceFile) ? sourceFile : path20.resolve(process.cwd(), sourceFile);
14629
+ const absolute = path21.isAbsolute(sourceFile) ? sourceFile : path21.resolve(process.cwd(), sourceFile);
14574
14630
  if (!existsSync13(absolute))
14575
14631
  return null;
14576
14632
  try {
14577
- const content = readFileSync11(absolute, "utf8");
14633
+ const content = readFileSync12(absolute, "utf8");
14578
14634
  return typeof content === "string" ? content : null;
14579
14635
  } catch {
14580
14636
  return null;
@@ -14685,8 +14741,8 @@ var init_symbol_coordinates = __esm(() => {
14685
14741
 
14686
14742
  // ../cli/dist/extractors/manifest.js
14687
14743
  import { createHash as createHash9 } from "node:crypto";
14688
- import { existsSync as existsSync14, readFileSync as readFileSync12, statSync as statSync7 } from "node:fs";
14689
- import * as path21 from "node:path";
14744
+ import { existsSync as existsSync14, readFileSync as readFileSync13, statSync as statSync7 } from "node:fs";
14745
+ import * as path22 from "node:path";
14690
14746
  function inferEntityTypeFromId(id) {
14691
14747
  const upper = id.toUpperCase();
14692
14748
  if (upper.startsWith("REQ-"))
@@ -14859,14 +14915,14 @@ function resolveCoordinatesPath(manifestPath, coordinatesPath) {
14859
14915
  if (coordinatesPath) {
14860
14916
  return coordinatesPath;
14861
14917
  }
14862
- return path21.join(path21.dirname(manifestPath), path21.basename(DEFAULT_COORDINATES_PATH));
14918
+ return path22.join(path22.dirname(manifestPath), path22.basename(DEFAULT_COORDINATES_PATH));
14863
14919
  }
14864
14920
  function readCoordinateArtifactFromFile(coordinatesPath) {
14865
14921
  if (!existsSync14(coordinatesPath)) {
14866
14922
  return null;
14867
14923
  }
14868
14924
  try {
14869
- const parsed = parseCoordinateArtifact(readFileSync12(coordinatesPath, "utf8"));
14925
+ const parsed = parseCoordinateArtifact(readFileSync13(coordinatesPath, "utf8"));
14870
14926
  if (parsed.status === "invalid") {
14871
14927
  throw new ManifestError(parsed.reason, coordinatesPath, "coordinate-artifact");
14872
14928
  }
@@ -14880,17 +14936,17 @@ function readCoordinateArtifactFromFile(coordinatesPath) {
14880
14936
  }
14881
14937
  function sourceTextResolver(manifestPath) {
14882
14938
  const bases = [process.cwd()];
14883
- const grandparent = path21.resolve(path21.dirname(path21.dirname(manifestPath)));
14939
+ const grandparent = path22.resolve(path22.dirname(path22.dirname(manifestPath)));
14884
14940
  if (!bases.includes(grandparent))
14885
14941
  bases.push(grandparent);
14886
14942
  return (sourceFile) => {
14887
14943
  let resolved = null;
14888
14944
  for (const base of bases) {
14889
- const absolute = path21.isAbsolute(sourceFile) ? sourceFile : path21.resolve(base, sourceFile);
14945
+ const absolute = path22.isAbsolute(sourceFile) ? sourceFile : path22.resolve(base, sourceFile);
14890
14946
  if (!existsSync14(absolute))
14891
14947
  continue;
14892
14948
  try {
14893
- const content = readFileSync12(absolute, "utf8");
14949
+ const content = readFileSync13(absolute, "utf8");
14894
14950
  if (typeof content === "string") {
14895
14951
  resolved = content;
14896
14952
  break;
@@ -14901,7 +14957,7 @@ function sourceTextResolver(manifestPath) {
14901
14957
  };
14902
14958
  }
14903
14959
  function readManifestWithCoordinateOverlay(manifestPath, coordinatesPath) {
14904
- const manifestContent = readFileSync12(manifestPath, "utf8");
14960
+ const manifestContent = readFileSync13(manifestPath, "utf8");
14905
14961
  const manifestRecords = extractManifestSymbolRecordsString(manifestContent, manifestPath);
14906
14962
  const coordinateArtifact = readCoordinateArtifactFromFile(resolveCoordinatesPath(manifestPath, coordinatesPath));
14907
14963
  return mergeCoordinatesWithManifest(manifestRecords, coordinateArtifact, {
@@ -14923,7 +14979,7 @@ function scopeSourceFiles(manifestPath) {
14923
14979
  return hit.sourceFiles;
14924
14980
  const sourceFiles = new Map;
14925
14981
  if (stamp !== "missing") {
14926
- const records = extractManifestSymbolRecordsString(readFileSync12(manifestPath, "utf8"), manifestPath);
14982
+ const records = extractManifestSymbolRecordsString(readFileSync13(manifestPath, "utf8"), manifestPath);
14927
14983
  for (const record of records) {
14928
14984
  const sourceFile = typeof record.sourceFile === "string" && record.sourceFile !== "" ? record.sourceFile : typeof record.source === "string" && record.source !== "" ? record.source : undefined;
14929
14985
  if (typeof record.id === "string" && sourceFile !== undefined) {
@@ -14941,7 +14997,7 @@ function scopeFileHash(absolutePath) {
14941
14997
  const hit = scopeFileHashCache.get(absolutePath);
14942
14998
  if (hit && hit.stamp === stamp)
14943
14999
  return hit.hash;
14944
- const hash = createHash9("sha256").update(readFileSync12(absolutePath)).digest("hex");
15000
+ const hash = createHash9("sha256").update(readFileSync13(absolutePath)).digest("hex");
14945
15001
  scopeFileHashCache.set(absolutePath, { stamp, hash });
14946
15002
  return hash;
14947
15003
  }
@@ -14950,7 +15006,7 @@ function resolveBoundSymbolScope(manifestPath, symbolIds) {
14950
15006
  if (wanted.length === 0)
14951
15007
  return [];
14952
15008
  const sourceFiles = scopeSourceFiles(manifestPath);
14953
- const workspaceRoot = path21.dirname(path21.dirname(path21.resolve(manifestPath)));
15009
+ const workspaceRoot = path22.dirname(path22.dirname(path22.resolve(manifestPath)));
14954
15010
  const scope = [];
14955
15011
  for (const symbolId of wanted) {
14956
15012
  const sourceFile = sourceFiles.get(symbolId);
@@ -14959,7 +15015,7 @@ function resolveBoundSymbolScope(manifestPath, symbolIds) {
14959
15015
  const relative = normalizeRepoRelativePath(workspaceRoot, sourceFile);
14960
15016
  scope.push({
14961
15017
  symbolId,
14962
- sourceHash: relative === null ? OUTSIDE_WORKSPACE_SCOPE_HASH : scopeFileHash(path21.join(workspaceRoot, relative))
15018
+ sourceHash: relative === null ? OUTSIDE_WORKSPACE_SCOPE_HASH : scopeFileHash(path22.join(workspaceRoot, relative))
14963
15019
  });
14964
15020
  }
14965
15021
  scope.sort((left, right) => left.symbolId.localeCompare(right.symbolId));
@@ -22477,7 +22533,7 @@ var init_proof_receipt = __esm(() => {
22477
22533
 
22478
22534
  // ../cli/dist/extractors/markdown.js
22479
22535
  import { createHash as createHash11 } from "node:crypto";
22480
- import { readFileSync as readFileSync13 } from "node:fs";
22536
+ import { readFileSync as readFileSync14 } from "node:fs";
22481
22537
  function validateExtractedEntity() {
22482
22538
  extractedEntityValidator ??= ajv.compile(entity_schema_default);
22483
22539
  return extractedEntityValidator;
@@ -22956,7 +23012,7 @@ function extractFromMarkdownString(content, filePath) {
22956
23012
  function extractFromMarkdown(filePath) {
22957
23013
  let content;
22958
23014
  try {
22959
- content = readFileSync13(filePath, "utf8");
23015
+ content = readFileSync14(filePath, "utf8");
22960
23016
  } catch (error) {
22961
23017
  throw new FrontmatterError(`Failed to read file: ${error instanceof Error ? error.message : String(error)}`, filePath, { classification: "File Read Error" });
22962
23018
  }
@@ -23461,7 +23517,7 @@ var init_rule_registry = __esm(() => {
23461
23517
 
23462
23518
  // ../cli/dist/utils/strict-modeling.js
23463
23519
  import { createHash as createHash12 } from "node:crypto";
23464
- import * as path22 from "node:path";
23520
+ import * as path23 from "node:path";
23465
23521
  function normalizeSubjectKey2(value) {
23466
23522
  const normalized = value.trim().toLowerCase().replace(/[\\/]+/g, ".").replace(/[^a-z0-9.]+/g, "_").replace(/_+/g, "_").replace(/\.+/g, ".").replace(/(^[._]+|[._]+$)/g, "");
23467
23523
  if (!normalized) {
@@ -23791,7 +23847,7 @@ function resolveEntitySourcePaths() {
23791
23847
  };
23792
23848
  }
23793
23849
  function normalizeEntityDirectory(directory) {
23794
- return directory.split(path22.sep).join("/").replace(/\/+$/g, "");
23850
+ return directory.split(path23.sep).join("/").replace(/\/+$/g, "");
23795
23851
  }
23796
23852
  function buildEntitySourcePath(directory, entityId) {
23797
23853
  return `${directory}/${entityId}.md`;
@@ -24903,9 +24959,9 @@ function cleanPredicate(value) {
24903
24959
  }
24904
24960
 
24905
24961
  // ../cli/dist/operations/modeling/requirement-heuristics.js
24906
- import path23 from "node:path";
24962
+ import path24 from "node:path";
24907
24963
  function fallbackSubjectFromSource(source) {
24908
- const basename = path23.basename(source, path23.extname(source)).replace(/[-_]+/g, " ").trim();
24964
+ const basename = path24.basename(source, path24.extname(source)).replace(/[-_]+/g, " ").trim();
24909
24965
  return basename || "Requirement";
24910
24966
  }
24911
24967
  function buildFallbackClaim(statement, source, confidence, provenance) {
@@ -26205,7 +26261,7 @@ var init_project_config = __esm(() => {
26205
26261
 
26206
26262
  // ../cli/dist/plugins/resolve-package.js
26207
26263
  import * as fs3 from "node:fs";
26208
- import { createRequire as createRequire3 } from "node:module";
26264
+ import { createRequire as createRequire4 } from "node:module";
26209
26265
  import { dirname as dirname6, isAbsolute as isAbsolute5, join as join12, relative as relative2, resolve as resolve6 } from "node:path";
26210
26266
  import { pathToFileURL } from "node:url";
26211
26267
  function readJson(path) {
@@ -26361,7 +26417,7 @@ function resolveProjectLocalPackage(workspaceRoot, packageName) {
26361
26417
  if (!hasDeclaredProjectDependency(root, packageName, manifest)) {
26362
26418
  throw new PluginResolutionError("UNDECLARED_DEPENDENCY", `Plugin package '${packageName}' must be listed in dependencies, devDependencies, or optionalDependencies of ${join12(root, "package.json")}`);
26363
26419
  }
26364
- const consumerRequire = createRequire3(join12(root, "package.json"));
26420
+ const consumerRequire = createRequire4(join12(root, "package.json"));
26365
26421
  let packageInfo = null;
26366
26422
  try {
26367
26423
  packageInfo = packageJsonForResolvedFile(consumerRequire.resolve(`${packageName}/package.json`), packageName);
@@ -26754,10 +26810,10 @@ var init_registry = __esm(() => {
26754
26810
  });
26755
26811
 
26756
26812
  // ../cli/dist/operations/modeling/vocabulary-alignment.js
26757
- import path24 from "node:path";
26813
+ import path25 from "node:path";
26758
26814
  import { rankSubjectCandidates } from "kibi-plugin-builtin";
26759
26815
  function semanticQualityModulePath() {
26760
- return path24.join(path24.dirname(resolveKbPlPath()), "semantic_quality.pl");
26816
+ return path25.join(path25.dirname(resolveKbPlPath()), "semantic_quality.pl");
26761
26817
  }
26762
26818
  function parseJsonBinding(raw) {
26763
26819
  if (raw === undefined || raw === "")
@@ -27730,7 +27786,7 @@ var init_requirement_claims = __esm(() => {
27730
27786
  });
27731
27787
 
27732
27788
  // ../cli/dist/operations/bootstrap/markdown-candidates.js
27733
- import path25 from "node:path";
27789
+ import path26 from "node:path";
27734
27790
  function headingSignals(heading, sourcePath, textRef, minConfidence) {
27735
27791
  const result = [];
27736
27792
  for (const [kind, pattern, confidence] of [
@@ -27756,7 +27812,7 @@ function genericHeadingCandidate(item, heading, line, existingIds, minConfidence
27756
27812
  const confidence = type === "adr" ? 0.9 : type === "fact" ? 0.8 : 0;
27757
27813
  if (!type || confidence < minConfidence)
27758
27814
  return null;
27759
- const id = `${type === "adr" ? "ADR" : "FACT"}-GEN-${slug(heading, 60) || slug(path25.basename(relativePath))}`.toUpperCase();
27815
+ const id = `${type === "adr" ? "ADR" : "FACT"}-GEN-${slug(heading, 60) || slug(path26.basename(relativePath))}`.toUpperCase();
27760
27816
  if (existingIds.has(id))
27761
27817
  return null;
27762
27818
  const entity = {
@@ -27922,7 +27978,7 @@ var init_markdown_candidates = __esm(() => {
27922
27978
  });
27923
27979
 
27924
27980
  // ../cli/dist/operations/bootstrap/candidates.js
27925
- import path26 from "node:path";
27981
+ import path27 from "node:path";
27926
27982
  function typedCandidates(item, existingIds) {
27927
27983
  const results = item.kind === "symbol_manifest" ? extractFromManifestString(item.content ?? "", item.relativePath ?? item.label) : [
27928
27984
  extractFromMarkdownString(item.content ?? "", item.relativePath ?? item.label)
@@ -27967,7 +28023,7 @@ function providerCandidate(item, existingIds, minConfidence) {
27967
28023
  const id = `FACT-GEN-${slug(`${item.kind}-${relativePath}`, 64) || "evidence"}`.toUpperCase();
27968
28024
  if (confidence < minConfidence || existingIds.has(id))
27969
28025
  return [];
27970
- const symbolTitle = item.kind === "source_symbols" && /\.(?:[cm]?[jt]sx?)$/i.test(relativePath) ? `Source symbols: ${path26.basename(relativePath, path26.extname(relativePath))}` : undefined;
28026
+ const symbolTitle = item.kind === "source_symbols" && /\.(?:[cm]?[jt]sx?)$/i.test(relativePath) ? `Source symbols: ${path27.basename(relativePath, path27.extname(relativePath))}` : undefined;
27971
28027
  const title = (typeof item.data.title === "string" ? item.data.title : undefined) ?? symbolTitle ?? `Bootstrap evidence from ${relativePath}`;
27972
28028
  const entity = {
27973
28029
  type: "fact",
@@ -28084,7 +28140,7 @@ var init_cli_errors = __esm(() => {
28084
28140
  });
28085
28141
 
28086
28142
  // ../cli/dist/operations/bootstrap/discovery-evidence.js
28087
- import path27 from "node:path";
28143
+ import path28 from "node:path";
28088
28144
  function isScanFilesystem(value) {
28089
28145
  return Boolean(value && "glob" in value && typeof value.glob === "function");
28090
28146
  }
@@ -28114,7 +28170,7 @@ function classifyFile(relativePath, content) {
28114
28170
  function evidenceData(provider, relativePath, content) {
28115
28171
  if (provider === "repo_metadata") {
28116
28172
  const languages = new Set;
28117
- if (/^package\.json$/i.test(path27.basename(relativePath))) {
28173
+ if (/^package\.json$/i.test(path28.basename(relativePath))) {
28118
28174
  try {
28119
28175
  const parsed = JSON.parse(content);
28120
28176
  const text = JSON.stringify(parsed);
@@ -28131,7 +28187,7 @@ function evidenceData(provider, relativePath, content) {
28131
28187
  if (/pyproject\.toml$/i.test(relativePath))
28132
28188
  languages.add("python");
28133
28189
  return {
28134
- title: `Repository metadata: ${path27.basename(relativePath)}`,
28190
+ title: `Repository metadata: ${path28.basename(relativePath)}`,
28135
28191
  factKind: "meta",
28136
28192
  confidence: relativePath.includes("tsconfig") ? 0.9 : 0.86,
28137
28193
  evidence: [`repo_metadata:${relativePath}`],
@@ -28158,7 +28214,7 @@ function evidenceData(provider, relativePath, content) {
28158
28214
  if (provider === "source_symbols") {
28159
28215
  const symbolCount = Array.from(content.matchAll(/\b(?:export\s+)?(?:function|class|const|let|var|interface|type)\s+([A-Za-z_$][\w$]*)/g)).length;
28160
28216
  return {
28161
- title: `Source module: ${path27.basename(relativePath, path27.extname(relativePath))}`,
28217
+ title: `Source module: ${path28.basename(relativePath, path28.extname(relativePath))}`,
28162
28218
  factKind: "observation",
28163
28219
  confidence: 0.82,
28164
28220
  evidence: [`source_symbols:${relativePath}`],
@@ -28177,7 +28233,7 @@ function layoutEvidence(workspaceRoot, files, ignored) {
28177
28233
  kind: "repo_layout",
28178
28234
  label: root,
28179
28235
  relativePath: root,
28180
- absolutePath: path27.join(workspaceRoot, root),
28236
+ absolutePath: path28.join(workspaceRoot, root),
28181
28237
  data: {
28182
28238
  title: `Repository layout: ${root} directory`,
28183
28239
  factKind: "observation",
@@ -28206,14 +28262,14 @@ async function scanEvidence(context) {
28206
28262
  for (const relativePath of files) {
28207
28263
  if (ignored.has(relativePath))
28208
28264
  continue;
28209
- const absolutePath = path27.resolve(context.workspaceRoot, relativePath);
28265
+ const absolutePath = path28.resolve(context.workspaceRoot, relativePath);
28210
28266
  try {
28211
28267
  const content = await fs.readFile(absolutePath);
28212
28268
  const classification = classifyFile(relativePath, content);
28213
28269
  if (!classification)
28214
28270
  continue;
28215
28271
  const [provider, kind] = classification;
28216
- if (provider === "repo_metadata" && path27.basename(relativePath) === "package.json") {
28272
+ if (provider === "repo_metadata" && path28.basename(relativePath) === "package.json") {
28217
28273
  try {
28218
28274
  JSON.parse(content);
28219
28275
  } catch {
@@ -28315,7 +28371,7 @@ var init_types = __esm(() => {
28315
28371
  });
28316
28372
 
28317
28373
  // ../cli/dist/operations/bootstrap/discovery.js
28318
- import path28 from "node:path";
28374
+ import path29 from "node:path";
28319
28375
  async function migrationWarning(context) {
28320
28376
  try {
28321
28377
  const status = readKbManifestStatus(context.workspaceRoot);
@@ -28329,7 +28385,7 @@ async function migrationWarning(context) {
28329
28385
  function languages(evidence) {
28330
28386
  return [
28331
28387
  ...new Set(evidence.flatMap((item) => {
28332
- const extension = path28.extname(item.label).slice(1);
28388
+ const extension = path29.extname(item.label).slice(1);
28333
28389
  const fromExtension = item.kind === "source_symbols" ? [LANGUAGE_NAMES[extension] ?? extension] : [];
28334
28390
  const fromMetadata = Array.isArray(item.data.languages) ? item.data.languages.filter((value) => typeof value === "string") : [];
28335
28391
  return [...fromExtension, ...fromMetadata];
@@ -28697,12 +28753,12 @@ var init_intent_claims = __esm(() => {
28697
28753
  });
28698
28754
 
28699
28755
  // ../cli/dist/operations/bootstrap/guidance-actions.js
28700
- import path29 from "node:path";
28756
+ import path30 from "node:path";
28701
28757
  function relative3(root, target) {
28702
- if (!path29.isAbsolute(target))
28758
+ if (!path30.isAbsolute(target))
28703
28759
  return target;
28704
- const value = path29.relative(root, target);
28705
- return value.startsWith("..") || path29.isAbsolute(value) ? target.split(path29.sep).join("/") : value.split(path29.sep).join("/");
28760
+ const value = path30.relative(root, target);
28761
+ return value.startsWith("..") || path30.isAbsolute(value) ? target.split(path30.sep).join("/") : value.split(path30.sep).join("/");
28706
28762
  }
28707
28763
  function summary(values, limit = 3) {
28708
28764
  if (values.length === 0)
@@ -28770,12 +28826,12 @@ function buildActions(root, activation, declared, candidates, signals) {
28770
28826
  var init_guidance_actions = () => {};
28771
28827
 
28772
28828
  // ../cli/dist/operations/bootstrap/guidance.js
28773
- import path30 from "node:path";
28829
+ import path31 from "node:path";
28774
28830
  function relative4(root, target) {
28775
- if (!path30.isAbsolute(target))
28831
+ if (!path31.isAbsolute(target))
28776
28832
  return target;
28777
- const value = path30.relative(root, target);
28778
- return value.startsWith("..") || path30.isAbsolute(value) ? target.split(path30.sep).join("/") : value.split(path30.sep).join("/");
28833
+ const value = path31.relative(root, target);
28834
+ return value.startsWith("..") || path31.isAbsolute(value) ? target.split(path31.sep).join("/") : value.split(path31.sep).join("/");
28779
28835
  }
28780
28836
  function summary2(values, limit = 3) {
28781
28837
  if (values.length === 0)
@@ -31262,7 +31318,7 @@ var init_validation2 = __esm(() => {
31262
31318
 
31263
31319
  // ../cli/dist/operations/bootstrap/generate.js
31264
31320
  import { createHash as createHash18 } from "node:crypto";
31265
- import path31 from "node:path";
31321
+ import path32 from "node:path";
31266
31322
  function filterSourceOnlySignals(signals, entityTypes) {
31267
31323
  return entityTypes && entityTypes.length > 0 ? signals.filter((signal) => entityTypes.includes(signal.kind)) : signals;
31268
31324
  }
@@ -31437,7 +31493,7 @@ async function expectedSnapshots(context, evidencePaths) {
31437
31493
  } else {
31438
31494
  for (const relative of new Set(evidencePaths)) {
31439
31495
  try {
31440
- const resolved = path31.resolve(context.workspaceRoot, relative);
31496
+ const resolved = path32.resolve(context.workspaceRoot, relative);
31441
31497
  if (!(await context.fs.stat(resolved)).isFile())
31442
31498
  continue;
31443
31499
  sourceHashes[relative] = sha2562(await context.fs.readFile(resolved));
@@ -31761,7 +31817,7 @@ var init_bootstrap = __esm(() => {
31761
31817
  });
31762
31818
 
31763
31819
  // ../cli/dist/commands/aggregated-checks.js
31764
- import path32 from "node:path";
31820
+ import path33 from "node:path";
31765
31821
  function ontologyQualitySetting(raw) {
31766
31822
  if (raw === undefined || raw.trim() === "")
31767
31823
  return "default";
@@ -31778,7 +31834,7 @@ function ontologyQualityOverridesGoal(env = process.env) {
31778
31834
  }
31779
31835
  async function runAggregatedChecks(prolog, rulesAllowlist) {
31780
31836
  const violations = [];
31781
- const checksPlPath = path32.join(path32.dirname(resolveKbPlPath()), "checks.pl");
31837
+ const checksPlPath = path33.join(path33.dirname(resolveKbPlPath()), "checks.pl");
31782
31838
  const checksPlPathEscaped = escapeAtom(checksPlPath);
31783
31839
  const fallbackQuery = `( predicate_property(checks:check_all_json_with_options(_, _), _)
31784
31840
  -> call(checks:check_all_json_with_options(JsonString, false))
@@ -32497,7 +32553,7 @@ var init_source_classification = __esm(() => {
32497
32553
 
32498
32554
  // ../cli/dist/plugins/source-analysis-service.js
32499
32555
  import { createHash as createHash20 } from "node:crypto";
32500
- import * as path33 from "node:path";
32556
+ import * as path34 from "node:path";
32501
32557
  function detectSourceLanguage(filePath) {
32502
32558
  return extensionLanguage(filePath);
32503
32559
  }
@@ -32544,9 +32600,9 @@ function providerBudgetMs(hostTimeoutMs) {
32544
32600
  return Math.max(1, hostTimeoutMs - grace);
32545
32601
  }
32546
32602
  function inferModuleTitle(filePath) {
32547
- const extension = path33.extname(filePath);
32548
- const basename = path33.basename(filePath, extension);
32549
- return basename.length > 0 ? basename : path33.basename(filePath);
32603
+ const extension = path34.extname(filePath);
32604
+ const basename = path34.basename(filePath, extension);
32605
+ return basename.length > 0 ? basename : path34.basename(filePath);
32550
32606
  }
32551
32607
  function createConservativeFallbackAnalysis(filePath, fallbackReason) {
32552
32608
  const language = detectSourceLanguage(filePath);
@@ -32787,8 +32843,8 @@ var init_source_analysis_service = __esm(() => {
32787
32843
 
32788
32844
  // ../cli/dist/plugins/maintenance-source-analysis.js
32789
32845
  import { createHash as createHash21 } from "node:crypto";
32790
- import { readFileSync as readFileSync16, realpathSync as realpathSync5 } from "node:fs";
32791
- import { createRequire as createRequire4 } from "node:module";
32846
+ import { readFileSync as readFileSync17, realpathSync as realpathSync5 } from "node:fs";
32847
+ import { createRequire as createRequire5 } from "node:module";
32792
32848
  import { dirname as dirname7, isAbsolute as isAbsolute6, join as join13, relative as relative5, resolve as resolve7 } from "node:path";
32793
32849
  function digestFile(root, file) {
32794
32850
  const candidate = resolve7(root, file);
@@ -32799,7 +32855,7 @@ function digestFile(root, file) {
32799
32855
  const actualRel = relative5(realpathSync5(root), actual);
32800
32856
  if (actualRel.startsWith("..") || isAbsolute6(actualRel))
32801
32857
  throw new Error(`Approved asset escapes its package: ${file}`);
32802
- return createHash21("sha256").update(readFileSync16(actual)).digest("hex");
32858
+ return createHash21("sha256").update(readFileSync17(actual)).digest("hex");
32803
32859
  }
32804
32860
  function verifyFiles(root, files) {
32805
32861
  if (Object.keys(files).length === 0)
@@ -32810,11 +32866,11 @@ function verifyFiles(root, files) {
32810
32866
  }
32811
32867
  }
32812
32868
  function dependencyRoot(importer, packageName) {
32813
- const require2 = createRequire4(join13(importer, "package.json"));
32869
+ const require2 = createRequire5(join13(importer, "package.json"));
32814
32870
  let current = dirname7(require2.resolve(packageName));
32815
32871
  for (;; ) {
32816
32872
  try {
32817
- const json = JSON.parse(readFileSync16(join13(current, "package.json"), "utf8"));
32873
+ const json = JSON.parse(readFileSync17(join13(current, "package.json"), "utf8"));
32818
32874
  if (json.name === packageName)
32819
32875
  return current;
32820
32876
  } catch {}
@@ -32825,7 +32881,7 @@ function dependencyRoot(importer, packageName) {
32825
32881
  }
32826
32882
  }
32827
32883
  function builtinRuntimeIdentity() {
32828
- const manifest = createRequire4(import.meta.url)("kibi-plugin-builtin/package.json");
32884
+ const manifest = createRequire5(import.meta.url)("kibi-plugin-builtin/package.json");
32829
32885
  if (manifest.name !== "kibi-plugin-builtin" || typeof manifest.version !== "string")
32830
32886
  throw new Error("Builtin source analyzer identity is invalid");
32831
32887
  return { name: manifest.name, version: manifest.version };
@@ -32858,13 +32914,13 @@ function fingerprintMaintenanceSourceSet(workspaceRoot, projectConfig) {
32858
32914
  }
32859
32915
  function verifyApprovedSourceAnalyzer(root, approval) {
32860
32916
  verifyFiles(root, approval.files);
32861
- const manifest = JSON.parse(readFileSync16(join13(root, "package.json"), "utf8"));
32917
+ const manifest = JSON.parse(readFileSync17(join13(root, "package.json"), "utf8"));
32862
32918
  if (manifest.name !== approval.packageName || manifest.version !== approval.version)
32863
32919
  throw new Error("Source analyzer package identity does not match host approval");
32864
32920
  for (const dependency of approval.dependencies) {
32865
32921
  const depRoot = dependencyRoot(root, dependency.packageName);
32866
32922
  verifyFiles(depRoot, dependency.files);
32867
- const metadata = JSON.parse(readFileSync16(join13(depRoot, "package.json"), "utf8"));
32923
+ const metadata = JSON.parse(readFileSync17(join13(depRoot, "package.json"), "utf8"));
32868
32924
  if (metadata.version !== dependency.version)
32869
32925
  throw new Error(`Unapproved source runtime version: ${dependency.packageName}`);
32870
32926
  }
@@ -40403,9 +40459,9 @@ var init_dist2 = __esm(() => {
40403
40459
  // ../cli/dist/relationships/shards.js
40404
40460
  import * as crypto from "node:crypto";
40405
40461
  import * as fs4 from "node:fs";
40406
- import * as path34 from "node:path";
40462
+ import * as path35 from "node:path";
40407
40463
  function getRelationshipsDir(kbRoot) {
40408
- return path34.join(kbRoot, "relationships");
40464
+ return path35.join(kbRoot, "relationships");
40409
40465
  }
40410
40466
  function shardForFromId(fromId) {
40411
40467
  const hash = crypto.createHash("sha256").update(fromId).digest("hex");
@@ -40413,7 +40469,7 @@ function shardForFromId(fromId) {
40413
40469
  }
40414
40470
  function computeShardPath(kbRoot, entityId) {
40415
40471
  const shardName = shardForFromId(entityId);
40416
- return path34.join(getRelationshipsDir(kbRoot), `${shardName}.yaml`);
40472
+ return path35.join(getRelationshipsDir(kbRoot), `${shardName}.yaml`);
40417
40473
  }
40418
40474
  function readShard(shardPath) {
40419
40475
  if (!fs4.existsSync(shardPath)) {
@@ -40585,7 +40641,7 @@ function appendRelationship(kbRoot, relationship) {
40585
40641
  const next = renderShardWithRelationship(shardPath, existing, relationship);
40586
40642
  if (next !== null) {
40587
40643
  if (existing === null) {
40588
- fs4.mkdirSync(path34.dirname(shardPath), { recursive: true });
40644
+ fs4.mkdirSync(path35.dirname(shardPath), { recursive: true });
40589
40645
  }
40590
40646
  atomicWriteText(shardPath, next);
40591
40647
  }
@@ -40618,7 +40674,7 @@ function listShards(kbRoot) {
40618
40674
  if (!fs4.existsSync(relationshipsDir)) {
40619
40675
  return [];
40620
40676
  }
40621
- return fs4.readdirSync(relationshipsDir).filter((f) => f.endsWith(".yaml")).map((f) => path34.join(relationshipsDir, f));
40677
+ return fs4.readdirSync(relationshipsDir).filter((f) => f.endsWith(".yaml")).map((f) => path35.join(relationshipsDir, f));
40622
40678
  }
40623
40679
  function readAllShards(kbRoot) {
40624
40680
  const shards = listShards(kbRoot);
@@ -40639,7 +40695,7 @@ var init_shards = __esm(() => {
40639
40695
  });
40640
40696
 
40641
40697
  // ../cli/dist/extractors/relationships.js
40642
- import * as path35 from "node:path";
40698
+ import * as path36 from "node:path";
40643
40699
  function extractRelationshipShard(shardPath) {
40644
40700
  try {
40645
40701
  const records = readShard(shardPath);
@@ -40672,7 +40728,7 @@ function convertRecordToRelationship(record) {
40672
40728
  return relationship;
40673
40729
  }
40674
40730
  function getRelationshipsDir2(kbRoot) {
40675
- return path35.join(kbRoot, "relationships");
40731
+ return path36.join(kbRoot, "relationships");
40676
40732
  }
40677
40733
  function validateRelationships(relationships, validEntityIds) {
40678
40734
  const errors = [];
@@ -41079,8 +41135,8 @@ var init_symbol_extract = __esm(() => {
41079
41135
  });
41080
41136
 
41081
41137
  // ../cli/dist/public/impact/diagnostics.js
41082
- import { existsSync as existsSync18, readFileSync as readFileSync18 } from "node:fs";
41083
- import * as path36 from "node:path";
41138
+ import { existsSync as existsSync18, readFileSync as readFileSync19 } from "node:fs";
41139
+ import * as path37 from "node:path";
41084
41140
  function isNarrowerSymbol(manifestSymbolName, candidate, sourceSymbols) {
41085
41141
  if (candidate.name === manifestSymbolName)
41086
41142
  return false;
@@ -41104,14 +41160,14 @@ function readSourceSymbols(sourceFile, sourceContentByFile, workspaceRoot) {
41104
41160
  content: stagedContent
41105
41161
  });
41106
41162
  }
41107
- const absolutePath = path36.isAbsolute(sourceFile) ? sourceFile : path36.resolve(workspaceRoot, sourceFile);
41163
+ const absolutePath = path37.isAbsolute(sourceFile) ? sourceFile : path37.resolve(workspaceRoot, sourceFile);
41108
41164
  if (!existsSync18(absolutePath))
41109
41165
  return [];
41110
41166
  return extractSymbolsFromStagedFile({
41111
41167
  path: sourceFile,
41112
41168
  status: "M",
41113
41169
  hunkRanges: [{ start: 1, end: Number.MAX_SAFE_INTEGER }],
41114
- content: readFileSync18(absolutePath, "utf8")
41170
+ content: readFileSync19(absolutePath, "utf8")
41115
41171
  });
41116
41172
  }
41117
41173
  function getGranularSymbolsForSourceFile(sourceFile, options2) {
@@ -41477,14 +41533,14 @@ function hasMeaningfulSourceDiff(diffText) {
41477
41533
 
41478
41534
  // ../cli/dist/public/impact/source-changes.js
41479
41535
  import { execFileSync as execFileSync3, execSync as execSync2 } from "node:child_process";
41480
- import { existsSync as existsSync19, lstatSync as lstatSync4, readFileSync as readFileSync19, realpathSync as realpathSync6 } from "node:fs";
41481
- import * as path37 from "node:path";
41536
+ import { existsSync as existsSync19, lstatSync as lstatSync4, readFileSync as readFileSync20, realpathSync as realpathSync6 } from "node:fs";
41537
+ import * as path38 from "node:path";
41482
41538
  function isSupportedSourcePath(filePath) {
41483
41539
  return isQualifiedSourcePath(filePath);
41484
41540
  }
41485
41541
  function normalizeSourceFile(workspaceRoot, sourceFile) {
41486
- const relativePath = path37.isAbsolute(sourceFile) ? path37.relative(workspaceRoot, sourceFile) : sourceFile;
41487
- return relativePath.split(path37.sep).join("/");
41542
+ const relativePath = path38.isAbsolute(sourceFile) ? path38.relative(workspaceRoot, sourceFile) : sourceFile;
41543
+ return relativePath.split(path38.sep).join("/");
41488
41544
  }
41489
41545
  function uniqueSorted2(values) {
41490
41546
  return [...new Set(values)].sort();
@@ -41497,16 +41553,16 @@ function runGit3(workspaceRoot, args) {
41497
41553
  });
41498
41554
  }
41499
41555
  function readWorkingTreeSource(workspaceRoot, sourceFile) {
41500
- const absolutePath = path37.resolve(workspaceRoot, sourceFile);
41501
- const relative = path37.relative(workspaceRoot, absolutePath);
41502
- if (!relative || relative.startsWith("..") || path37.isAbsolute(relative))
41556
+ const absolutePath = path38.resolve(workspaceRoot, sourceFile);
41557
+ const relative = path38.relative(workspaceRoot, absolutePath);
41558
+ if (!relative || relative.startsWith("..") || path38.isAbsolute(relative))
41503
41559
  throw new Error("Source path must remain inside the workspace");
41504
41560
  if (!existsSync19(absolutePath) || !lstatSync4(absolutePath).isFile())
41505
41561
  return null;
41506
- const actualRelative = path37.relative(realpathSync6(workspaceRoot), realpathSync6(absolutePath));
41507
- if (actualRelative.startsWith("..") || path37.isAbsolute(actualRelative))
41562
+ const actualRelative = path38.relative(realpathSync6(workspaceRoot), realpathSync6(absolutePath));
41563
+ if (actualRelative.startsWith("..") || path38.isAbsolute(actualRelative))
41508
41564
  throw new Error("Source path escapes the workspace");
41509
- const bytes = readFileSync19(absolutePath);
41565
+ const bytes = readFileSync20(absolutePath);
41510
41566
  if (bytes.includes(0))
41511
41567
  return null;
41512
41568
  try {
@@ -41582,7 +41638,7 @@ function getExplicitSourceChanges(workspaceRoot, sourceFileFilter) {
41582
41638
  });
41583
41639
  }
41584
41640
  function collectSourceChanges(options2) {
41585
- const workspaceRoot = path37.resolve(options2.workspaceRoot);
41641
+ const workspaceRoot = path38.resolve(options2.workspaceRoot);
41586
41642
  const sourceFileFilter = new Set((options2.sourceFiles ?? []).map((sourceFile) => normalizeSourceFile(workspaceRoot, sourceFile)).filter(isSupportedSourcePath));
41587
41643
  if (options2.staged)
41588
41644
  return getStagedSourceChanges(workspaceRoot, sourceFileFilter);
@@ -41598,13 +41654,13 @@ var init_source_changes = __esm(() => {
41598
41654
 
41599
41655
  // ../cli/dist/public/impact/manifest.js
41600
41656
  import { existsSync as existsSync20 } from "node:fs";
41601
- import * as path38 from "node:path";
41657
+ import * as path39 from "node:path";
41602
41658
  function toTraceabilityRelationships(relationships) {
41603
41659
  return relationships.filter((relationship) => isTraceabilityRelationshipType(relationship.type)).map((relationship) => ({ type: relationship.type, to: relationship.to }));
41604
41660
  }
41605
41661
  function readImpactManifestResults(workspaceRoot) {
41606
41662
  const symbolsPath = CANONICAL_ENTITY_PATHS.symbols;
41607
- const absolutePath = path38.isAbsolute(symbolsPath) ? symbolsPath : path38.resolve(workspaceRoot, symbolsPath);
41663
+ const absolutePath = path39.isAbsolute(symbolsPath) ? symbolsPath : path39.resolve(workspaceRoot, symbolsPath);
41608
41664
  if (!existsSync20(absolutePath))
41609
41665
  return [];
41610
41666
  return extractFromManifest(absolutePath).map((result) => ({
@@ -41965,9 +42021,9 @@ var init_symbol_quality = __esm(() => {
41965
42021
  });
41966
42022
 
41967
42023
  // ../cli/dist/public/impact/analyzer.js
41968
- import * as path39 from "node:path";
42024
+ import * as path40 from "node:path";
41969
42025
  async function analyzeChangedFileImpact(options2) {
41970
- const workspaceRoot = path39.resolve(options2.workspaceRoot);
42026
+ const workspaceRoot = path40.resolve(options2.workspaceRoot);
41971
42027
  const snapshot = options2.staged ? captureStagedSnapshot(workspaceRoot) : undefined;
41972
42028
  const filter = new Set((options2.sourceFiles ?? []).map((file) => normalizeSourceFile(workspaceRoot, file)));
41973
42029
  const snapshotAnalysisInventory = snapshot ? snapshot.inventory.filter((file) => filter.size === 0 || filter.has(file.path)) : undefined;
@@ -43055,7 +43111,7 @@ var init_requirement_quality = __esm(() => {
43055
43111
 
43056
43112
  // ../cli/dist/public/impact/full-kb-quality.js
43057
43113
  import { readFile } from "node:fs/promises";
43058
- import path40 from "node:path";
43114
+ import path41 from "node:path";
43059
43115
  function stringField(entity, key) {
43060
43116
  const value = entity[key];
43061
43117
  return typeof value === "string" ? value : "";
@@ -43485,7 +43541,7 @@ function telemetryReadDiagnostic(message) {
43485
43541
  async function collectTelemetryDiagnostics(workspaceRoot, now) {
43486
43542
  if (workspaceRoot === undefined)
43487
43543
  return [];
43488
- const usageLogPath = path40.join(workspaceRoot, ".kb", "usage.log");
43544
+ const usageLogPath = path41.join(workspaceRoot, ".kb", "usage.log");
43489
43545
  let contents;
43490
43546
  try {
43491
43547
  contents = await readFile(usageLogPath, "utf8");
@@ -43661,7 +43717,7 @@ function buildSummary(input) {
43661
43717
  }
43662
43718
 
43663
43719
  // ../cli/dist/utils/entity-id-style.js
43664
- import * as path41 from "node:path";
43720
+ import * as path42 from "node:path";
43665
43721
  function isNumericEntityId(id) {
43666
43722
  return NUMERIC_ENTITY_ID_PATTERN.test(id.trim());
43667
43723
  }
@@ -43672,7 +43728,7 @@ function markdownSourceStem(sourcePath) {
43672
43728
  if (!normalized.endsWith(".md") || normalized.includes("://")) {
43673
43729
  return;
43674
43730
  }
43675
- return path41.posix.basename(normalized, ".md");
43731
+ return path42.posix.basename(normalized, ".md");
43676
43732
  }
43677
43733
  function entityIdStyleIssues(input) {
43678
43734
  const id = input.id.trim();
@@ -43798,8 +43854,8 @@ var init_prolog_query_plan_safety = __esm(() => {
43798
43854
 
43799
43855
  // ../cli/dist/public/operations/check-helpers.js
43800
43856
  import { execSync as execSync3 } from "node:child_process";
43801
- import { readFileSync as readFileSync20 } from "node:fs";
43802
- import path42 from "node:path";
43857
+ import { readFileSync as readFileSync21 } from "node:fs";
43858
+ import path43 from "node:path";
43803
43859
  function partitionCheckFindings(findings) {
43804
43860
  const violations = [];
43805
43861
  const qualityDiagnostics = [];
@@ -43826,11 +43882,11 @@ function partitionCheckFindings(findings) {
43826
43882
  }
43827
43883
  function resolveChecksPlPath() {
43828
43884
  const override = getKbPlPathOverride();
43829
- return path42.join(path42.dirname(override ?? resolveKbPlPath()), "checks.pl");
43885
+ return path43.join(path43.dirname(override ?? resolveKbPlPath()), "checks.pl");
43830
43886
  }
43831
43887
  function collectQueryPlanSafetyViolations() {
43832
43888
  const checksPlPath = resolveChecksPlPath();
43833
- const source = readFileSync20(checksPlPath, "utf8");
43889
+ const source = readFileSync21(checksPlPath, "utf8");
43834
43890
  return analyzePrologQueryPlanSafety(source).map((v) => ({
43835
43891
  rule: "query-plan-safety",
43836
43892
  entityId: v.predicate,
@@ -43888,8 +43944,8 @@ var init_check_helpers = __esm(() => {
43888
43944
  });
43889
43945
 
43890
43946
  // ../cli/dist/operations/migration/kb-sources.js
43891
- import { existsSync as existsSync21, mkdirSync as mkdirSync7, readFileSync as readFileSync21, readdirSync as readdirSync5, renameSync as renameSync4, writeFileSync as writeFileSync6 } from "node:fs";
43892
- import path43 from "node:path";
43947
+ import { existsSync as existsSync21, mkdirSync as mkdirSync7, readFileSync as readFileSync22, readdirSync as readdirSync5, renameSync as renameSync4, writeFileSync as writeFileSync6 } from "node:fs";
43948
+ import path44 from "node:path";
43893
43949
  import { isDeepStrictEqual } from "node:util";
43894
43950
  function walkMarkdown(directory, files) {
43895
43951
  let entries;
@@ -43899,7 +43955,7 @@ function walkMarkdown(directory, files) {
43899
43955
  return;
43900
43956
  }
43901
43957
  for (const entry of entries) {
43902
- const absolute = path43.join(directory, entry.name);
43958
+ const absolute = path44.join(directory, entry.name);
43903
43959
  if (entry.isDirectory()) {
43904
43960
  walkMarkdown(absolute, files);
43905
43961
  } else if (entry.isFile() && entry.name.endsWith(".md") && entry.name !== "README.md") {
@@ -43911,7 +43967,7 @@ function listLaneMarkdownFiles(workspaceRoot, lanes = ENTITY_LANES) {
43911
43967
  const result = [];
43912
43968
  for (const lane of lanes) {
43913
43969
  const files = [];
43914
- const laneRoot = path43.join(workspaceRoot, KB_PATHS.lanes[lane]);
43970
+ const laneRoot = path44.join(workspaceRoot, KB_PATHS.lanes[lane]);
43915
43971
  if (!existsSync21(laneRoot))
43916
43972
  continue;
43917
43973
  walkMarkdown(laneRoot, files);
@@ -43919,7 +43975,7 @@ function listLaneMarkdownFiles(workspaceRoot, lanes = ENTITY_LANES) {
43919
43975
  result.push({
43920
43976
  lane,
43921
43977
  absolutePath,
43922
- relativePath: path43.relative(workspaceRoot, absolutePath).replaceAll(path43.sep, "/")
43978
+ relativePath: path44.relative(workspaceRoot, absolutePath).replaceAll(path44.sep, "/")
43923
43979
  });
43924
43980
  }
43925
43981
  }
@@ -44047,14 +44103,14 @@ function withoutTopLevelField(content, key) {
44047
44103
  return match === null ? content : `${slice.prefix}${text}${slice.suffix}`;
44048
44104
  }
44049
44105
  function writeFileAtomically(filePath, content) {
44050
- mkdirSync7(path43.dirname(filePath), { recursive: true });
44106
+ mkdirSync7(path44.dirname(filePath), { recursive: true });
44051
44107
  const tempPath = `${filePath}.kibi-migrate-${process.pid}-${Date.now()}`;
44052
44108
  writeFileSync6(tempPath, content, "utf8");
44053
44109
  renameSync4(tempPath, filePath);
44054
44110
  }
44055
44111
  function readText(filePath) {
44056
44112
  try {
44057
- return readFileSync21(filePath, "utf8");
44113
+ return readFileSync22(filePath, "utf8");
44058
44114
  } catch {
44059
44115
  return null;
44060
44116
  }
@@ -44065,7 +44121,7 @@ var init_kb_sources = __esm(() => {
44065
44121
  });
44066
44122
 
44067
44123
  // ../cli/dist/public/operations/entity-context.js
44068
- import path44 from "node:path";
44124
+ import path45 from "node:path";
44069
44125
  function readAuthoredEntity(content, relativePath) {
44070
44126
  const slice = sliceFrontmatter(content);
44071
44127
  if (slice === null)
@@ -44081,7 +44137,7 @@ function readAuthoredEntity(content, relativePath) {
44081
44137
  }
44082
44138
  const record = data;
44083
44139
  const type = typeof record.type === "string" ? record.type : inferTypeFromPath(relativePath) ?? "";
44084
- const id = typeof record.id === "string" && record.id.trim() !== "" ? record.id.trim() : path44.basename(relativePath, ".md");
44140
+ const id = typeof record.id === "string" && record.id.trim() !== "" ? record.id.trim() : path45.basename(relativePath, ".md");
44085
44141
  const newline = slice.suffix.indexOf(`
44086
44142
  `);
44087
44143
  return {
@@ -44139,7 +44195,7 @@ function authoredSupersededIds(workspaceRoot, entities) {
44139
44195
  }
44140
44196
  }
44141
44197
  try {
44142
- for (const relationship of readAllShards(path44.join(workspaceRoot, ".kb"))) {
44198
+ for (const relationship of readAllShards(path45.join(workspaceRoot, ".kb"))) {
44143
44199
  if (relationship.type === "supersedes")
44144
44200
  superseded.add(relationship.to);
44145
44201
  }
@@ -44228,8 +44284,8 @@ var init_entity_context = __esm(() => {
44228
44284
  });
44229
44285
 
44230
44286
  // ../cli/dist/public/operations/origin-review.js
44231
- import { readFileSync as readFileSync22 } from "node:fs";
44232
- import path45 from "node:path";
44287
+ import { readFileSync as readFileSync23 } from "node:fs";
44288
+ import path46 from "node:path";
44233
44289
  function markdownHasRationaleSection(content) {
44234
44290
  const body = content.startsWith("---") ? content.replace(/^---\r?\n[\s\S]*?\r?\n---[ \t]*(?:\r?\n|$)/, "") : content;
44235
44291
  return RATIONALE_HEADING.test(body);
@@ -44240,13 +44296,13 @@ function rationaleSectionReader(workspaceRoot) {
44240
44296
  const source = text3(entity.source);
44241
44297
  if (source === undefined || !source.endsWith(".md"))
44242
44298
  return false;
44243
- const file = path45.resolve(workspaceRoot, source);
44299
+ const file = path46.resolve(workspaceRoot, source);
44244
44300
  const cached = cache.get(file);
44245
44301
  if (cached !== undefined)
44246
44302
  return cached;
44247
44303
  let found = false;
44248
44304
  try {
44249
- found = markdownHasRationaleSection(readFileSync22(file, "utf8"));
44305
+ found = markdownHasRationaleSection(readFileSync23(file, "utf8"));
44250
44306
  } catch {
44251
44307
  found = false;
44252
44308
  }
@@ -46585,7 +46641,7 @@ var init_predicate_schema_conformance = __esm(() => {
46585
46641
 
46586
46642
  // ../cli/dist/operations/migration/source-paths.js
46587
46643
  import { existsSync as existsSync22 } from "node:fs";
46588
- import path46 from "node:path";
46644
+ import path47 from "node:path";
46589
46645
  function scalarText(value) {
46590
46646
  if (typeof value === "string")
46591
46647
  return value.trim();
@@ -46609,7 +46665,7 @@ function scanAuthoredSources(workspaceRoot) {
46609
46665
  const slice = sliceFrontmatter(content);
46610
46666
  if (slice === null)
46611
46667
  continue;
46612
- const id = scalarText(readTopLevelField(slice.text, "id")) || path46.basename(file.relativePath, ".md");
46668
+ const id = scalarText(readTopLevelField(slice.text, "id")) || path47.basename(file.relativePath, ".md");
46613
46669
  entityIds.add(id);
46614
46670
  const value = readTopLevelField(slice.text, "source");
46615
46671
  if (value === undefined || value === null)
@@ -46618,7 +46674,7 @@ function scanAuthoredSources(workspaceRoot) {
46618
46674
  continue;
46619
46675
  refs.push({ entityId: id, file: file.relativePath, value });
46620
46676
  }
46621
- const symbols = readText(path46.join(workspaceRoot, KB_PATHS.symbolsManifest));
46677
+ const symbols = readText(path47.join(workspaceRoot, KB_PATHS.symbolsManifest));
46622
46678
  if (symbols !== null) {
46623
46679
  for (const match of symbols.matchAll(SYMBOL_ID_LINE)) {
46624
46680
  const id = unquote(match[1] ?? "");
@@ -46664,15 +46720,15 @@ function resolveAuthoredSource(value, context) {
46664
46720
  return { kind: "dangling" };
46665
46721
  }
46666
46722
  function workspacePathExists(workspaceRoot) {
46667
- const root = path46.resolve(workspaceRoot);
46723
+ const root = path47.resolve(workspaceRoot);
46668
46724
  const cache = new Map;
46669
46725
  return (relativePath) => {
46670
46726
  const cached = cache.get(relativePath);
46671
46727
  if (cached !== undefined)
46672
46728
  return cached;
46673
- const absolute = path46.resolve(root, relativePath);
46674
- const fromRoot = path46.relative(root, absolute);
46675
- const exists = !fromRoot.startsWith("..") && !path46.isAbsolute(fromRoot) && existsSync22(absolute);
46729
+ const absolute = path47.resolve(root, relativePath);
46730
+ const fromRoot = path47.relative(root, absolute);
46731
+ const exists = !fromRoot.startsWith("..") && !path47.isAbsolute(fromRoot) && existsSync22(absolute);
46676
46732
  cache.set(relativePath, exists);
46677
46733
  return exists;
46678
46734
  };
@@ -46714,7 +46770,7 @@ function classifySources(workspaceRoot) {
46714
46770
  }
46715
46771
  function withEditability(workspaceRoot, repairs) {
46716
46772
  return repairs.map((repair) => {
46717
- const content = readText(path46.join(workspaceRoot, repair.file));
46773
+ const content = readText(path47.join(workspaceRoot, repair.file));
46718
46774
  if (content !== null && editedContent(content, repair.fix) !== null) {
46719
46775
  return repair;
46720
46776
  }
@@ -46782,7 +46838,7 @@ function applySourcePathRepairs(workspaceRoot, planned) {
46782
46838
  continue;
46783
46839
  }
46784
46840
  }
46785
- const absolute = path46.join(workspaceRoot, repair.file);
46841
+ const absolute = path47.join(workspaceRoot, repair.file);
46786
46842
  const content = readText(absolute);
46787
46843
  const next = content === null ? null : editedContent(content, repair.fix);
46788
46844
  if (next === null) {
@@ -52345,15 +52401,15 @@ var require_out4 = __commonJS(function(exports2, module2) {
52345
52401
  import { execFile } from "node:child_process";
52346
52402
  import { createHash as createHash24 } from "node:crypto";
52347
52403
  import * as fs5 from "node:fs";
52348
- import { existsSync as existsSync23, readFileSync as readFileSync24, readdirSync as readdirSync6, unlinkSync as unlinkSync4 } from "node:fs";
52349
- import * as path47 from "node:path";
52404
+ import { existsSync as existsSync23, readFileSync as readFileSync25, readdirSync as readdirSync6, unlinkSync as unlinkSync4 } from "node:fs";
52405
+ import * as path48 from "node:path";
52350
52406
  import { promisify } from "node:util";
52351
52407
  async function gitTrackedPaths(cwd) {
52352
52408
  const result = await execFileAsync("git", ["-C", cwd, "ls-files", "--cached", "-z", "--"], { encoding: "buffer", maxBuffer: 64 * 1024 * 1024 });
52353
52409
  return new Set(result.stdout.toString("utf8").split("\x00").filter(Boolean).map((value) => value.replaceAll("\\", "/")));
52354
52410
  }
52355
52411
  function pendingSourcePaths(cwd, recoverMissing) {
52356
- const root = path47.join(cwd, ".kb", "recovery", "pending-sources");
52412
+ const root = path48.join(cwd, ".kb", "recovery", "pending-sources");
52357
52413
  if (!existsSync23(root)) {
52358
52414
  return { paths: new Map, recoveredReceipts: [] };
52359
52415
  }
@@ -52362,14 +52418,14 @@ function pendingSourcePaths(cwd, recoverMissing) {
52362
52418
  for (const name of readdirSync6(root)) {
52363
52419
  if (!name.endsWith(".json"))
52364
52420
  continue;
52365
- const receiptPath = path47.join(root, name);
52421
+ const receiptPath = path48.join(root, name);
52366
52422
  try {
52367
- const raw = readFileSync24(receiptPath, "utf8");
52423
+ const raw = readFileSync25(receiptPath, "utf8");
52368
52424
  const receipt = JSON.parse(raw);
52369
52425
  if (typeof receipt.path === "string" && receipt.path.length > 0 && typeof receipt.afterHash === "string" && /^[a-f0-9]{64}$/i.test(receipt.afterHash)) {
52370
52426
  const relative = receipt.path.replaceAll("\\", "/");
52371
- const absolute = path47.resolve(cwd, relative);
52372
- if (!absolute.startsWith(`${path47.resolve(cwd)}${path47.sep}`)) {
52427
+ const absolute = path48.resolve(cwd, relative);
52428
+ if (!absolute.startsWith(`${path48.resolve(cwd)}${path48.sep}`)) {
52373
52429
  throw new Error(`Pending source receipt escapes workspace: ${relative}`);
52374
52430
  }
52375
52431
  if (!existsSync23(absolute)) {
@@ -52384,7 +52440,7 @@ function pendingSourcePaths(cwd, recoverMissing) {
52384
52440
  }
52385
52441
  throw new Error(`Pending source is missing: ${relative}. If the file was deleted on purpose, run 'kibi branch recover --apply' to rebuild the branch KB from the sources that remain.`);
52386
52442
  }
52387
- const actual = createHash24("sha256").update(readFileSync24(absolute)).digest("hex");
52443
+ const actual = createHash24("sha256").update(readFileSync25(absolute)).digest("hex");
52388
52444
  if (actual !== receipt.afterHash) {
52389
52445
  throw new Error(`Pending source hash drift blocks sync for ${relative}; expected ${receipt.afterHash}, found ${actual}`);
52390
52446
  }
@@ -52421,10 +52477,10 @@ function unlinkOrEnoent(absolute) {
52421
52477
  }
52422
52478
  }
52423
52479
  function clearRecoveredPendingSourceReceipts(cwd, receipts) {
52424
- const root = path47.resolve(cwd, ".kb", "recovery", "pending-sources");
52480
+ const root = path48.resolve(cwd, ".kb", "recovery", "pending-sources");
52425
52481
  for (const receipt of receipts) {
52426
- const absolute = path47.resolve(receipt.receiptPath);
52427
- if (!absolute.startsWith(`${root}${path47.sep}`)) {
52482
+ const absolute = path48.resolve(receipt.receiptPath);
52483
+ if (!absolute.startsWith(`${root}${path48.sep}`)) {
52428
52484
  throw new Error(`Pending source receipt escapes recovery root: ${absolute}`);
52429
52485
  }
52430
52486
  if (!existsSync23(absolute))
@@ -52451,7 +52507,7 @@ function clearRecoveredPendingSourceReceipts(cwd, receipts) {
52451
52507
  function filterTracked(cwd, files, tracked, pending) {
52452
52508
  const retained = [];
52453
52509
  for (const file of files) {
52454
- const relative = path47.relative(cwd, file).replaceAll(path47.sep, "/");
52510
+ const relative = path48.relative(cwd, file).replaceAll(path48.sep, "/");
52455
52511
  if (tracked.has(relative)) {
52456
52512
  retained.push(file);
52457
52513
  continue;
@@ -52500,7 +52556,7 @@ async function discoverSourceFiles(cwd, options2 = {}) {
52500
52556
  entityMarkdownFiles = filterTracked(cwd, entityMarkdownFiles, tracked, new Set(pending.paths.keys()));
52501
52557
  manifestFiles = filterTracked(cwd, manifestFiles, tracked, new Set(pending.paths.keys()));
52502
52558
  for (const relative of pending.paths.keys()) {
52503
- const absolute = path47.resolve(cwd, relative);
52559
+ const absolute = path48.resolve(cwd, relative);
52504
52560
  if (!existsSync23(absolute))
52505
52561
  continue;
52506
52562
  if (relative.endsWith(".md") && !entityMarkdownFiles.includes(absolute)) {
@@ -52510,21 +52566,21 @@ async function discoverSourceFiles(cwd, options2 = {}) {
52510
52566
  manifestFiles.push(absolute);
52511
52567
  }
52512
52568
  }
52513
- const pendingRoot = path47.join(cwd, ".kb", "recovery", "pending-sources");
52569
+ const pendingRoot = path48.join(cwd, ".kb", "recovery", "pending-sources");
52514
52570
  if (options2.consumeTrackedPendingReceipts !== false && existsSync23(pendingRoot)) {
52515
52571
  for (const name of readdirSync6(pendingRoot)) {
52516
52572
  if (!name.endsWith(".json"))
52517
52573
  continue;
52518
52574
  try {
52519
- const receipt = JSON.parse(readFileSync24(path47.join(pendingRoot, name), "utf8"));
52575
+ const receipt = JSON.parse(readFileSync25(path48.join(pendingRoot, name), "utf8"));
52520
52576
  if (typeof receipt.path === "string" && tracked.has(receipt.path.replaceAll("\\", "/"))) {
52521
- unlinkSync4(path47.join(pendingRoot, name));
52577
+ unlinkSync4(path48.join(pendingRoot, name));
52522
52578
  }
52523
52579
  } catch {}
52524
52580
  }
52525
52581
  }
52526
52582
  }
52527
- const relationshipsDir = getRelationshipsDir2(path47.join(cwd, ".kb"));
52583
+ const relationshipsDir = getRelationshipsDir2(path48.join(cwd, ".kb"));
52528
52584
  return {
52529
52585
  markdownFiles: entityMarkdownFiles,
52530
52586
  manifestFiles,
@@ -52542,15 +52598,15 @@ var init_discovery2 = __esm(() => {
52542
52598
  });
52543
52599
 
52544
52600
  // ../cli/dist/commands/sync/extraction.js
52545
- import * as path48 from "node:path";
52601
+ import * as path49 from "node:path";
52546
52602
  function normalizeExtractionSources(results, workspaceRoot) {
52547
- const root = path48.resolve(workspaceRoot);
52603
+ const root = path49.resolve(workspaceRoot);
52548
52604
  const normalize = (value) => {
52549
52605
  if (/^[A-Za-z][A-Za-z0-9+.-]*:\/\//.test(value))
52550
52606
  return value;
52551
- const absolute = path48.isAbsolute(value) ? path48.resolve(value) : undefined;
52552
- if (absolute?.startsWith(`${root}${path48.sep}`)) {
52553
- return path48.relative(root, absolute).replaceAll(path48.sep, "/");
52607
+ const absolute = path49.isAbsolute(value) ? path49.resolve(value) : undefined;
52608
+ if (absolute?.startsWith(`${root}${path49.sep}`)) {
52609
+ return path49.relative(root, absolute).replaceAll(path49.sep, "/");
52554
52610
  }
52555
52611
  return value.replaceAll("\\", "/");
52556
52612
  };
@@ -52903,7 +52959,7 @@ var init_relationships2 = __esm(() => {
52903
52959
 
52904
52960
  // ../cli/dist/public/operations/source-relationship-parity.js
52905
52961
  import { execFileSync as execFileSync4 } from "node:child_process";
52906
- import path49 from "node:path";
52962
+ import path50 from "node:path";
52907
52963
  function relationshipKey(relationship) {
52908
52964
  return `${relationship.type}\x00${relationship.from}\x00${relationship.to}`;
52909
52965
  }
@@ -53034,14 +53090,14 @@ async function collectSourceRelationshipParityViolations(workspaceRoot, prolog)
53034
53090
  if (extraction.errors.length > 0) {
53035
53091
  return extraction.errors.map(({ file, message }) => ({
53036
53092
  rule: "source-relationship-parity",
53037
- entityId: path49.relative(workspaceRoot, file).replaceAll(path49.sep, "/"),
53038
- source: path49.relative(workspaceRoot, file).replaceAll(path49.sep, "/"),
53093
+ entityId: path50.relative(workspaceRoot, file).replaceAll(path50.sep, "/"),
53094
+ source: path50.relative(workspaceRoot, file).replaceAll(path50.sep, "/"),
53039
53095
  description: `Authored relationship parity could not inspect source: ${message}`,
53040
53096
  suggestion: "Repair the authored source, then rerun kb_check."
53041
53097
  }));
53042
53098
  }
53043
53099
  const authored = extraction.results.flatMap(({ entity, relationships }) => relationships.map((relationship) => authoredRelationship(relationship, entity.source)));
53044
- for (const relationship of readAllShards(path49.join(workspaceRoot, ".kb"))) {
53100
+ for (const relationship of readAllShards(path50.join(workspaceRoot, ".kb"))) {
53045
53101
  authored.push({
53046
53102
  type: relationship.type,
53047
53103
  from: relationship.from,
@@ -54946,6 +55002,17 @@ function nameOrStopWordReason(value, context = {}) {
54946
55002
  return `it repeats the argument name ${token} and the claim does not name it`;
54947
55003
  return null;
54948
55004
  }
55005
+ function clauseBindingReason(value, context = {}) {
55006
+ const type = context.argumentType ? bindingToken(context.argumentType) : "";
55007
+ if (!NAMING_ARGUMENT_TYPES.has(type))
55008
+ return null;
55009
+ if (matchesConstant(value, context))
55010
+ return null;
55011
+ const words = bindingToken(value).split("_").filter(Boolean);
55012
+ if (words.length <= MAX_NAMING_BINDING_WORDS)
55013
+ return null;
55014
+ return `it is a ${words.length}-word clause of the claim, not a short name for this ${type}`;
55015
+ }
54949
55016
  function classifyBinding(value, text, explicit, canonical = false, context = {}) {
54950
55017
  const normalized = value.trim();
54951
55018
  if (nameOrStopWordReason(normalized, { ...context, text }) !== null)
@@ -54957,6 +55024,8 @@ function classifyBinding(value, text, explicit, canonical = false, context = {})
54957
55024
  return "explicit";
54958
55025
  if (!normalized || isGenericPlaceholder(normalized))
54959
55026
  return "placeholder";
55027
+ if (clauseBindingReason(normalized, context) !== null)
55028
+ return "placeholder";
54960
55029
  if (textContainsValue(text, normalized))
54961
55030
  return "extracted";
54962
55031
  return "inferred";
@@ -54967,7 +55036,7 @@ function aggregateBindingProvenance(values) {
54967
55036
  function bindingCanBeApplied(value) {
54968
55037
  return value === "explicit" || value === "requirement" || value === "extracted";
54969
55038
  }
54970
- var PLACEHOLDER_VALUES, DERIVED_CUE_ALIASES, STOP_WORD_BINDINGS, PROVENANCE_ORDER;
55039
+ var PLACEHOLDER_VALUES, DERIVED_CUE_ALIASES, STOP_WORD_BINDINGS, NAMING_ARGUMENT_TYPES, MAX_NAMING_BINDING_WORDS = 3, PROVENANCE_ORDER;
54971
55040
  var init_predicate_bindings = __esm(() => {
54972
55041
  PLACEHOLDER_VALUES = new Set([
54973
55042
  "unknown",
@@ -55108,6 +55177,15 @@ var init_predicate_bindings = __esm(() => {
55108
55177
  "example",
55109
55178
  "placeholder"
55110
55179
  ]);
55180
+ NAMING_ARGUMENT_TYPES = new Set([
55181
+ "entity",
55182
+ "actor",
55183
+ "actor_scope",
55184
+ "resource",
55185
+ "owner",
55186
+ "role",
55187
+ "component"
55188
+ ]);
55111
55189
  PROVENANCE_ORDER = [
55112
55190
  "explicit",
55113
55191
  "requirement",
@@ -55813,11 +55891,14 @@ function buildSuggestion(schema, text, subject, score, argumentBindings = {}, po
55813
55891
  const inferredArgs = inferArgs(schema, text, subject);
55814
55892
  const canonicalLauncherArgs = exactLauncherPredicateArgs(schema.predicate_name, text);
55815
55893
  const hasExactBinding = (name) => typeof argumentBindings[name] === "string" && argumentBindings[name].trim().length > 0;
55816
- const requirementSubjectArgument = diagnostics?.requirementSubject && diagnostics.explicitSubject !== true && !hasExactBinding("subject") ? schema.argument_names.indexOf("subject") : -1;
55894
+ const subjectArgument = schema.argument_names.indexOf("subject");
55895
+ const explicitSubject = diagnostics?.explicitSubject === true;
55896
+ const reviewedSubject = explicitSubject ? subject : diagnostics?.requirementSubject;
55897
+ const reviewedSubjectArgument = reviewedSubject !== undefined && !hasExactBinding("subject") ? subjectArgument : -1;
55817
55898
  const boundArgs = schema.argument_names.map((name, index) => {
55818
55899
  const exactBinding = argumentBindings[name];
55819
- if (index === requirementSubjectArgument)
55820
- return diagnostics?.requirementSubject ?? "unknown";
55900
+ if (index === reviewedSubjectArgument)
55901
+ return reviewedSubject ?? "unknown";
55821
55902
  return typeof exactBinding === "string" && exactBinding.trim().length > 0 ? exactBinding.trim() : inferredArgs[index] ?? "unknown";
55822
55903
  });
55823
55904
  const vocabulary = {
@@ -55827,16 +55908,26 @@ function buildSuggestion(schema, text, subject, score, argumentBindings = {}, po
55827
55908
  const conformance = predicateArgumentConformance(schema.argument_names, boundArgs, vocabulary);
55828
55909
  const predicateArgs = applyArgumentRewrites(boundArgs, conformance.rewrites);
55829
55910
  const undeclaredArguments = new Set(conformance.undeclared.map((value) => value.argumentName));
55911
+ const hintedFirstArgument = explicitSubject && subjectArgument < 0 && !hasExactBinding(schema.argument_names[0] ?? "") && predicateArgs[0] === subject ? 0 : -1;
55830
55912
  const bindingProvenanceByArgument = Object.fromEntries(schema.argument_names.map((name, index) => [
55831
55913
  name,
55832
- index === requirementSubjectArgument && !undeclaredArguments.has(name) ? "requirement" : classifyBinding(predicateArgs[index] ?? "unknown", text, typeof argumentBindings[name] === "string" && argumentBindings[name].trim().length > 0 || diagnostics?.explicitSubject === true && index === 0, canonicalLauncherArgs?.[index] === predicateArgs[index] && !(index === 0 && predicateArgs[index] === "launcher" && diagnostics?.explicitSubject !== true && typeof argumentBindings[name] !== "string"), index === 0 && diagnostics?.explicitSubject === true && typeof argumentBindings[name] !== "string" ? { constants: schema.argument_constants?.[name] } : {
55914
+ index === reviewedSubjectArgument && !undeclaredArguments.has(name) ? explicitSubject ? classifyBinding(predicateArgs[index] ?? "unknown", text, true) : "requirement" : classifyBinding(predicateArgs[index] ?? "unknown", text, hasExactBinding(name) || index === hintedFirstArgument, canonicalLauncherArgs?.[index] === predicateArgs[index] && !(index === 0 && predicateArgs[index] === "launcher" && !explicitSubject && typeof argumentBindings[name] !== "string"), index === hintedFirstArgument ? { constants: schema.argument_constants?.[name] } : {
55833
55915
  argumentName: name,
55834
55916
  argumentNames: schema.argument_names,
55917
+ argumentType: schema.argument_types[index],
55835
55918
  constants: schema.argument_constants?.[name]
55836
55919
  })
55837
55920
  ]));
55921
+ const constrainedSubjects = diagnostics?.constrainedSubjects ?? [];
55922
+ const subjectKey = constrainedSubjects.length === 0 ? null : subjectArgument >= 0 ? predicateArgs[subjectArgument] ?? null : reviewedSubject ?? null;
55923
+ const subjectPairing = constrainedSubjects.length === 0 ? "not_required" : subjectKey !== null && constrainedSubjects.includes(subjectKey) ? "paired" : "unpaired";
55838
55924
  const bindingProvenance = aggregateBindingProvenance(Object.values(bindingProvenanceByArgument));
55839
55925
  const unboundArguments = schema.argument_names.filter((name) => undeclaredArguments.has(name) || !bindingCanBeApplied(bindingProvenanceByArgument[name] ?? "placeholder"));
55926
+ if (subjectPairing === "unpaired") {
55927
+ const missing = subjectArgument >= 0 ? "subject" : "subject_key";
55928
+ if (!unboundArguments.includes(missing))
55929
+ unboundArguments.push(missing);
55930
+ }
55840
55931
  const canonicalKey = `${schema.predicate_name}(${predicateArgs.join(",")})`;
55841
55932
  const polarity = polarityHint ?? (predicateArgs.at(-1) === "deny" || /\b(?:must\s+not|shall\s+not|never|cannot|can't|forbidden|prohibited)\b/i.test(text) ? "deny" : "assert");
55842
55933
  return {
@@ -55849,6 +55940,8 @@ function buildSuggestion(schema, text, subject, score, argumentBindings = {}, po
55849
55940
  unbound_arguments: unboundArguments,
55850
55941
  binding_provenance: bindingProvenance,
55851
55942
  binding_provenance_by_argument: bindingProvenanceByArgument,
55943
+ subject_key: subjectKey,
55944
+ subject_pairing: subjectPairing,
55852
55945
  eligibility: diagnostics?.eligibility ?? "eligible",
55853
55946
  rejection_reasons: [...diagnostics?.rejectionReasons ?? []],
55854
55947
  applicability_score: diagnostics?.applicabilityScore ?? score,
@@ -55891,6 +55984,7 @@ function buildPredicateApplyPlan(suggestion, args) {
55891
55984
  ...suggestion.schema.tags.map((tag) => `predicate:${tag}`)
55892
55985
  ],
55893
55986
  fact_kind: "predicate",
55987
+ ...suggestion.subject_key ? { subject_key: suggestion.subject_key } : {},
55894
55988
  predicate_name: suggestion.predicate_name,
55895
55989
  predicate_args: suggestion.predicate_args,
55896
55990
  canonical_key: suggestion.canonical_key,
@@ -56057,6 +56151,12 @@ function unboundReason(candidate, name, value, text) {
56057
56151
  });
56058
56152
  if (nameReason !== null)
56059
56153
  return `The value "${value}" is not a binding: ${nameReason}.`;
56154
+ const clauseReason = clauseBindingReason(value, {
56155
+ argumentType: schema.argument_types[schema.argument_names.indexOf(name)],
56156
+ constants: schema.argument_constants?.[name]
56157
+ });
56158
+ if (clauseReason !== null)
56159
+ return `The value "${value}" is not a binding: ${clauseReason}. Bind a noun of at most 3 words, or the requirement's subject key.`;
56060
56160
  if (!value.trim() || isGenericPlaceholder(value))
56061
56161
  return "The claim text names no value for this argument.";
56062
56162
  if (provenance === "inferred")
@@ -56068,12 +56168,26 @@ function unboundReason(candidate, name, value, text) {
56068
56168
  function buildBindingHints(candidate, text, requirementSubjects = []) {
56069
56169
  const schema = candidate.schema;
56070
56170
  const parsedExamples = schema.examples.map(exampleArguments);
56171
+ const namesSubject = schema.argument_names.includes("subject");
56071
56172
  return candidate.unbound_arguments.map((name) => {
56173
+ if (name === "subject_key" && !namesSubject)
56174
+ return {
56175
+ argument: name,
56176
+ position: -1,
56177
+ type: "subject_key",
56178
+ description: "The subject the predicate fact is about; recorded as its subject_key because the schema names no subject argument.",
56179
+ examples: requirementSubjects.slice(0, MAX_EXAMPLES),
56180
+ currentValue: candidate.subject_key ?? "",
56181
+ provenance: "placeholder",
56182
+ reason: `The ${schema.predicate_name} schema does not name the requirement's subject, so kb_check pairs the predicate with the subject fact only through subject_key. Pass subjectHint with one of the subjects the requirement constrains.`
56183
+ };
56072
56184
  const position = schema.argument_names.indexOf(name);
56073
56185
  const constants = schema.argument_constants?.[name];
56074
56186
  const exampleValues = parsedExamples.map((args) => args[position]).filter((value) => typeof value === "string");
56075
56187
  const examples = Array.from(new Set([
56076
- ...name === "subject" ? requirementSubjects : [],
56188
+ ...name === "subject" || !namesSubject && clauseBindingReason(candidate.predicate_args[position] ?? "", {
56189
+ argumentType: schema.argument_types[position]
56190
+ }) !== null ? requirementSubjects : [],
56077
56191
  ...constants ?? [],
56078
56192
  ...exampleValues
56079
56193
  ])).slice(0, MAX_EXAMPLES);
@@ -56088,7 +56202,7 @@ function buildBindingHints(candidate, text, requirementSubjects = []) {
56088
56202
  examples,
56089
56203
  currentValue: current,
56090
56204
  provenance: candidate.binding_provenance_by_argument[name] ?? "placeholder",
56091
- reason: unboundReason(candidate, name, current, text)
56205
+ reason: name === "subject" && candidate.subject_pairing === "unpaired" && bindingCanBeApplied(candidate.binding_provenance_by_argument[name] ?? "placeholder") ? `The value "${current}" is not a subject the requirement constrains (${requirementSubjects.join(", ")}), so kb_check would not pair the predicate with the subject fact. Bind one of them.` : unboundReason(candidate, name, current, text)
56092
56206
  };
56093
56207
  });
56094
56208
  }
@@ -56275,8 +56389,8 @@ async function constrainedSubjectKeys(prolog, requirementId, warnings) {
56275
56389
  async function handleKbSuggestPredicates(prolog, args, context) {
56276
56390
  const text = normalizeText2(args.text);
56277
56391
  const warnings = [];
56278
- const requirementSubjects = hasSubjectHint(args.subjectHint) ? [] : await constrainedSubjectKeys(prolog, args.requirementId, warnings);
56279
- const requirementSubject = requirementSubjects.length === 1 ? requirementSubjects[0] : undefined;
56392
+ const requirementSubjects = await constrainedSubjectKeys(prolog, args.requirementId, warnings);
56393
+ const requirementSubject = !hasSubjectHint(args.subjectHint) && requirementSubjects.length === 1 ? requirementSubjects[0] : undefined;
56280
56394
  const subject = inferSubject(text, args.subjectHint, {
56281
56395
  requirementId: args.requirementId,
56282
56396
  subjectKey: requirementSubject
@@ -56322,7 +56436,8 @@ async function handleKbSuggestPredicates(prolog, args, context) {
56322
56436
  applicabilityScore: applicability.applicabilityScore,
56323
56437
  scoreComponents: ranked.components,
56324
56438
  explicitSubject: Boolean(args.subjectHint?.trim()),
56325
- ...requirementSubject ? { requirementSubject } : {}
56439
+ ...requirementSubject ? { requirementSubject } : {},
56440
+ constrainedSubjects: requirementSubjects
56326
56441
  });
56327
56442
  });
56328
56443
  const evaluatedCandidates = withMarginRejection(initialCandidates).sort((left, right) => {
@@ -56358,6 +56473,9 @@ async function handleKbSuggestPredicates(prolog, args, context) {
56358
56473
  warnings.push(`${args.requirementId} already grounds this claim (${claimKey}) through ${groundingSummary}. A modeled claim takes exactly one logical grounding relationship, so adding requires_predicate beside it fails the proposition-complete rule. ${replacementPlan ? "Keep the existing grounding, or follow replacementPlan to swap it for the predicate." : "Keep the existing grounding; no predicate replacement is available yet."}`);
56359
56474
  }
56360
56475
  const bindingHints = recommendedAction === "provide_argument_bindings" && recommendedCandidate ? buildBindingHints(recommendedCandidate, text, requirementSubjects) : [];
56476
+ if (recommendedCandidate?.subject_pairing === "unpaired") {
56477
+ warnings.push(unpairedSubjectWarning(recommendedCandidate, args, requirementSubjects));
56478
+ }
56361
56479
  const recommendedPredicateSchema = !recommendedCandidate && !unavailableSchema ? buildPredicateSchemaDraft(text, subject) : null;
56362
56480
  const groundedPrefix = alreadyGrounded ? `${args.requirementId} already grounds this claim through ${groundingSummary}. ` : "";
56363
56481
  const textSummary = groundedPrefix + (replacementPlan ? `To use ${completeCandidate?.predicate_name} instead, follow replacementPlan and link requires_predicate to ${plannedFactId}; otherwise keep the existing grounding.` : completeCandidate ? `Suggested ${candidates.length} predicate candidate(s). Top applicable match: ${completeCandidate.predicate_name}. Apply the predicate fact ${plannedFactId}, then link requires_predicate to that fact id (not a candidate id).` : recommendedCandidate ? `Matched ${recommendedCandidate.predicate_name}, but exact reviewed values are still required for: ${recommendedCandidate.unbound_arguments.join(", ")}. Bind them from the claim text: ${describeBindingHints(bindingHints)}. A value that repeats an argument name or a stop word stays unbound. No apply plan was generated.` : unavailableSchema ? `Requested predicate schema ${args.schemaId} is unavailable or semantically inapplicable. No apply plan was generated.` : alreadyGrounded ? "No predicate candidate passed the semantic applicability gate; keep the existing grounding and record the ontology-gap observation in applyPlan so the missing schema stays visible." : "No predicate candidate passed the semantic applicability gate; record an ontology gap and review the generated schema draft instead of silently writing prose.");
@@ -56385,6 +56503,12 @@ async function handleKbSuggestPredicates(prolog, args, context) {
56385
56503
  applyPlan
56386
56504
  };
56387
56505
  }
56506
+ function unpairedSubjectWarning(candidate, args, constrainedSubjects) {
56507
+ const subjects = constrainedSubjects.join(", ");
56508
+ const schemaNamesSubject = candidate.schema.argument_names.includes("subject");
56509
+ const cause = schemaNamesSubject ? `its subject argument is ${candidate.subject_key ?? "unbound"}, not a subject ${args.requirementId} constrains (${subjects})` : `the ${candidate.predicate_name} schema does not name the requirement's subject (its arguments are ${candidate.schema.argument_names.join(", ")}) and its subject_key ${candidate.subject_key === null ? "cannot be chosen" : `${candidate.subject_key} is not`} one of the subjects ${args.requirementId} constrains (${subjects})`;
56510
+ return `${candidate.predicate_name} is not offered for grounding because ${cause}, so kb_check would report strict-req-fact-pairing after the link. Pass subjectHint with one of ${subjects} and retry.`;
56511
+ }
56388
56512
  async function storedRequirementProperties(prolog, requirementId, warnings) {
56389
56513
  if (prolog === null)
56390
56514
  return null;
@@ -60351,7 +60475,7 @@ var require_gray_matter = __commonJS(function(exports2, module2) {
60351
60475
  });
60352
60476
 
60353
60477
  // ../cli/dist/public/skill-system/validation.js
60354
- import { existsSync as existsSync24, readFileSync as readFileSync25, realpathSync as realpathSync7, statSync as statSync9 } from "node:fs";
60478
+ import { existsSync as existsSync24, readFileSync as readFileSync26, realpathSync as realpathSync7, statSync as statSync9 } from "node:fs";
60355
60479
  import { dirname as dirname9, resolve as resolve15 } from "node:path";
60356
60480
  function assertMaxBytes(pathLike, maxBytes) {
60357
60481
  const size = statSync9(pathLike).size;
@@ -60361,7 +60485,7 @@ function assertMaxBytes(pathLike, maxBytes) {
60361
60485
  function parseSkillBundle(rootDir) {
60362
60486
  const path = resolve15(rootDir, SKILL_FILE_NAME);
60363
60487
  assertMaxBytes(path, SKILL_MARKDOWN_MAX_BYTES);
60364
- const parsed = import_gray_matter.default(readFileSync25(path, "utf8"));
60488
+ const parsed = import_gray_matter.default(readFileSync26(path, "utf8"));
60365
60489
  const [error] = validateManifestData(parsed.data);
60366
60490
  if (error)
60367
60491
  throw error;
@@ -60425,9 +60549,9 @@ var init_validation3 = __esm(() => {
60425
60549
  });
60426
60550
 
60427
60551
  // ../cli/dist/public/skill-system/loader.js
60428
- import { existsSync as existsSync25, readFileSync as readFileSync26, readdirSync as readdirSync7, realpathSync as realpathSync8 } from "node:fs";
60552
+ import { existsSync as existsSync25, readFileSync as readFileSync27, readdirSync as readdirSync7, realpathSync as realpathSync8 } from "node:fs";
60429
60553
  import { dirname as dirname10, join as join18, resolve as resolve16 } from "node:path";
60430
- import { fileURLToPath as fileURLToPath3 } from "node:url";
60554
+ import { fileURLToPath as fileURLToPath4 } from "node:url";
60431
60555
  function listBundledSkills() {
60432
60556
  return listFrom(bundledSkillsDir);
60433
60557
  }
@@ -60472,14 +60596,14 @@ function readBundle(bundle, id, resourcePath) {
60472
60596
  throw new SkillResourceNotFoundError(id, resourcePath);
60473
60597
  }
60474
60598
  assertMaxBytes(candidate, RESOURCE_MAX_BYTES);
60475
- return readFileSync26(candidate, "utf8");
60599
+ return readFileSync27(candidate, "utf8");
60476
60600
  }
60477
60601
  var defaultBundledSkillsDir, bundledSkillsDir;
60478
60602
  var init_loader = __esm(() => {
60479
60603
  init_errors();
60480
60604
  init_paths();
60481
60605
  init_validation3();
60482
- defaultBundledSkillsDir = resolve16(dirname10(fileURLToPath3(import.meta.url)), "../skills");
60606
+ defaultBundledSkillsDir = resolve16(dirname10(fileURLToPath4(import.meta.url)), "../skills");
60483
60607
  bundledSkillsDir = defaultBundledSkillsDir;
60484
60608
  });
60485
60609
 
@@ -62272,17 +62396,17 @@ var init_audit = __esm(() => {
62272
62396
  import { createHash as createHash27 } from "node:crypto";
62273
62397
  import { randomUUID as randomUUID2 } from "node:crypto";
62274
62398
  import fs6 from "node:fs";
62275
- import path50 from "node:path";
62399
+ import path51 from "node:path";
62276
62400
  import { isDeepStrictEqual as isDeepStrictEqual2 } from "node:util";
62277
62401
  function digest3(value) {
62278
62402
  return createHash27("sha256").update(value).digest("hex");
62279
62403
  }
62280
62404
  function pendingReceiptPath(workspaceRoot, relativePath) {
62281
- return path50.join(workspaceRoot, ".kb", "recovery", "pending-sources", `${digest3(relativePath)}.json`);
62405
+ return path51.join(workspaceRoot, ".kb", "recovery", "pending-sources", `${digest3(relativePath)}.json`);
62282
62406
  }
62283
62407
  function writePendingSourceReceipt(workspaceRoot, relativePath, afterHash) {
62284
62408
  const receiptPath = pendingReceiptPath(workspaceRoot, relativePath);
62285
- fs6.mkdirSync(path50.dirname(receiptPath), { recursive: true, mode: 448 });
62409
+ fs6.mkdirSync(path51.dirname(receiptPath), { recursive: true, mode: 448 });
62286
62410
  fs6.writeFileSync(receiptPath, `${JSON.stringify({
62287
62411
  version: 1,
62288
62412
  path: relativePath,
@@ -62310,34 +62434,34 @@ function authoredPath(value) {
62310
62434
  return normalized;
62311
62435
  }
62312
62436
  function resolveContainedSourcePath(workspaceRoot, relative) {
62313
- if (path50.isAbsolute(relative) || relative.split(/[\\/]/).some((part) => part === ".." || part === "")) {
62437
+ if (path51.isAbsolute(relative) || relative.split(/[\\/]/).some((part) => part === ".." || part === "")) {
62314
62438
  throw new OperationError("SOURCE_PATH_INVALID", `document.path must be a workspace-relative path without traversal: ${relative}`);
62315
62439
  }
62316
- const absolute = path50.resolve(workspaceRoot, relative);
62317
- const root = path50.resolve(workspaceRoot);
62318
- if (absolute !== root && !absolute.startsWith(`${root}${path50.sep}`)) {
62440
+ const absolute = path51.resolve(workspaceRoot, relative);
62441
+ const root = path51.resolve(workspaceRoot);
62442
+ if (absolute !== root && !absolute.startsWith(`${root}${path51.sep}`)) {
62319
62443
  throw new OperationError("SOURCE_PATH_INVALID", `document.path escapes the workspace: ${relative}`);
62320
62444
  }
62321
- const workspaceRelative = path50.relative(root, absolute).replaceAll(path50.sep, "/");
62445
+ const workspaceRelative = path51.relative(root, absolute).replaceAll(path51.sep, "/");
62322
62446
  if (isDerivedKbPath(workspaceRelative)) {
62323
62447
  throw new OperationError("SOURCE_PATH_INVALID", `document.path cannot target Kibi's derived state under ${workspaceRelative}: ${relative}`);
62324
62448
  }
62325
62449
  const realRoot = canonicalFilesystemPath(root);
62326
62450
  const real = canonicalFilesystemPath(absolute);
62327
- if (real !== realRoot && !real.startsWith(`${realRoot}${path50.sep}`)) {
62451
+ if (real !== realRoot && !real.startsWith(`${realRoot}${path51.sep}`)) {
62328
62452
  throw new OperationError("SOURCE_PATH_INVALID", `document.path resolves outside the workspace: ${relative}`);
62329
62453
  }
62330
62454
  return absolute;
62331
62455
  }
62332
62456
  function normalizeAuthoredSourcePath(workspaceRoot, source) {
62333
62457
  const normalized = source.replaceAll("\\", "/");
62334
- const root = path50.resolve(workspaceRoot);
62458
+ const root = path51.resolve(workspaceRoot);
62335
62459
  let relative = normalized;
62336
- if (path50.isAbsolute(normalized)) {
62337
- const absolute = path50.resolve(normalized);
62338
- relative = absolute === root || absolute.startsWith(`${root}${path50.sep}`) ? path50.relative(root, absolute) : path50.relative(canonicalFilesystemPath(root), canonicalFilesystemPath(absolute));
62460
+ if (path51.isAbsolute(normalized)) {
62461
+ const absolute = path51.resolve(normalized);
62462
+ relative = absolute === root || absolute.startsWith(`${root}${path51.sep}`) ? path51.relative(root, absolute) : path51.relative(canonicalFilesystemPath(root), canonicalFilesystemPath(absolute));
62339
62463
  }
62340
- return path50.relative(path50.resolve(workspaceRoot), resolveContainedSourcePath(workspaceRoot, relative)).replaceAll(path50.sep, "/");
62464
+ return path51.relative(path51.resolve(workspaceRoot), resolveContainedSourcePath(workspaceRoot, relative)).replaceAll(path51.sep, "/");
62341
62465
  }
62342
62466
  function bodyAndFrontmatter(content) {
62343
62467
  if (!content.startsWith("---"))
@@ -62383,13 +62507,13 @@ function sourcePath(context, input, entity, existing) {
62383
62507
  if (!relative) {
62384
62508
  throw new OperationError("DOCUMENT_PATH_REQUIRED", `No writable source target is available for ${input.type}; provide document.path explicitly`);
62385
62509
  }
62386
- if (path50.isAbsolute(relative)) {
62387
- const root = path50.resolve(context.workspaceRoot);
62388
- const absolute = path50.resolve(relative);
62389
- if (absolute !== root && !absolute.startsWith(`${root}${path50.sep}`)) {
62510
+ if (path51.isAbsolute(relative)) {
62511
+ const root = path51.resolve(context.workspaceRoot);
62512
+ const absolute = path51.resolve(relative);
62513
+ if (absolute !== root && !absolute.startsWith(`${root}${path51.sep}`)) {
62390
62514
  throw new OperationError("SOURCE_PATH_INVALID", `document.path resolves outside the workspace: ${relative}`);
62391
62515
  }
62392
- relative = path50.relative(root, absolute).replaceAll(path50.sep, "/");
62516
+ relative = path51.relative(root, absolute).replaceAll(path51.sep, "/");
62393
62517
  }
62394
62518
  return resolveContainedSourcePath(context.workspaceRoot, relative);
62395
62519
  }
@@ -62608,7 +62732,7 @@ function renderSymbolManifest(entity, relationships, existingContent) {
62608
62732
  return doc.toString(AUTHORED_YAML_OPTIONS);
62609
62733
  }
62610
62734
  function renderSourceDeletion(sourcePathValue, entityId, entityType, existingContent) {
62611
- const extension = path50.extname(sourcePathValue).toLowerCase();
62735
+ const extension = path51.extname(sourcePathValue).toLowerCase();
62612
62736
  if (extension === ".md" || extension === ".mdx") {
62613
62737
  const parsed = bodyAndFrontmatter(existingContent);
62614
62738
  if (String(parsed.frontmatter.id ?? "") !== entityId) {
@@ -62638,7 +62762,7 @@ function renderSourceDeletion(sourcePathValue, entityId, entityType, existingCon
62638
62762
  throw new OperationError("SOURCE_FORMAT_UNSUPPORTED", `Unsupported authored source format: ${extension || "unknown"}`);
62639
62763
  }
62640
62764
  function renderMarkdownRelationshipDeletion(sourcePathValue, existingContent, selector) {
62641
- const extension = path50.extname(sourcePathValue).toLowerCase();
62765
+ const extension = path51.extname(sourcePathValue).toLowerCase();
62642
62766
  if (extension !== ".md" && extension !== ".mdx") {
62643
62767
  throw new OperationError("SOURCE_FORMAT_UNSUPPORTED", `Relationship declarations can only be patched in Markdown documents: ${sourcePathValue}`);
62644
62768
  }
@@ -62697,7 +62821,7 @@ ${frontmatter.toString(AUTHORED_YAML_OPTIONS)}---${body.startsWith(`
62697
62821
  };
62698
62822
  }
62699
62823
  function renderYamlRelationshipDeletion(sourcePathValue, existingContent, selector) {
62700
- const extension = path50.extname(sourcePathValue).toLowerCase();
62824
+ const extension = path51.extname(sourcePathValue).toLowerCase();
62701
62825
  if (extension !== ".yaml" && extension !== ".yml") {
62702
62826
  throw new OperationError("SOURCE_FORMAT_UNSUPPORTED", `Relationship declarations can only be patched in YAML symbol manifests: ${sourcePathValue}`);
62703
62827
  }
@@ -62740,7 +62864,7 @@ function renderYamlRelationshipDeletion(sourcePathValue, existingContent, select
62740
62864
  return removed ? { body: doc.toString(AUTHORED_YAML_OPTIONS), removed: true } : { body: existingContent, removed: false };
62741
62865
  }
62742
62866
  function renderSourceDocument(input, entity, existingContent, relativePath) {
62743
- const extension = path50.extname(relativePath).toLowerCase();
62867
+ const extension = path51.extname(relativePath).toLowerCase();
62744
62868
  if (extension === ".yaml" || extension === ".yml") {
62745
62869
  if (input.type !== "symbol") {
62746
62870
  throw new OperationError("SOURCE_FORMAT_UNSUPPORTED", `YAML source authoring is supported only for symbol manifests, not ${input.type}`);
@@ -62756,7 +62880,7 @@ async function writeSourceForUpsert(input, entity, existing, context, sourceDocu
62756
62880
  if (!context?.fs)
62757
62881
  return null;
62758
62882
  const absolute = sourcePath(context, input, entity, existing);
62759
- const relative = path50.relative(context.workspaceRoot, absolute).replaceAll("\\", "/");
62883
+ const relative = path51.relative(context.workspaceRoot, absolute).replaceAll("\\", "/");
62760
62884
  let before;
62761
62885
  try {
62762
62886
  before = await context.fs.readFile(absolute);
@@ -62764,7 +62888,7 @@ async function writeSourceForUpsert(input, entity, existing, context, sourceDocu
62764
62888
  before = undefined;
62765
62889
  }
62766
62890
  const after = before !== undefined && sourceDocumentOverride !== undefined ? sourceDocumentOverride : renderSourceDocument(input, entity, before, relative);
62767
- await context.fs.mkdir(path50.dirname(absolute));
62891
+ await context.fs.mkdir(path51.dirname(absolute));
62768
62892
  const temporary = `${absolute}.kibi-source-${process.pid}-${randomUUID2()}`;
62769
62893
  try {
62770
62894
  await context.fs.writeFile(temporary, after);
@@ -62848,7 +62972,7 @@ async function writeSourceForUpsert(input, entity, existing, context, sourceDocu
62848
62972
  return { receipt, rollback };
62849
62973
  }
62850
62974
  function canonicalSourcePath(context, input, entity, existing) {
62851
- return path50.relative(context.workspaceRoot, sourcePath(context, input, entity, existing)).replaceAll(path50.sep, "/");
62975
+ return path51.relative(context.workspaceRoot, sourcePath(context, input, entity, existing)).replaceAll(path51.sep, "/");
62852
62976
  }
62853
62977
  var AUTHORED_YAML_OPTIONS, GENERATED_SYMBOL_FIELDS;
62854
62978
  var init_source_authoring = __esm(() => {
@@ -62870,8 +62994,8 @@ var init_source_authoring = __esm(() => {
62870
62994
 
62871
62995
  // ../cli/dist/operations/mutation/plan-apply-journal.js
62872
62996
  import { createHash as createHash28, randomUUID as randomUUID3 } from "node:crypto";
62873
- import { closeSync as closeSync3, existsSync as existsSync26, fsyncSync as fsyncSync2, mkdirSync as mkdirSync8, openSync as openSync3, readFileSync as readFileSync27, readdirSync as readdirSync8, renameSync as renameSync5, statSync as statSync10, unlinkSync as unlinkSync5, writeSync as writeSync2 } from "node:fs";
62874
- import path51 from "node:path";
62997
+ import { closeSync as closeSync3, existsSync as existsSync26, fsyncSync as fsyncSync2, mkdirSync as mkdirSync8, openSync as openSync3, readFileSync as readFileSync28, readdirSync as readdirSync8, renameSync as renameSync5, statSync as statSync10, unlinkSync as unlinkSync5, writeSync as writeSync2 } from "node:fs";
62998
+ import path52 from "node:path";
62875
62999
  function planApplyJournalId(planHash) {
62876
63000
  return `plan-apply-${planHash.slice(0, 16).toLowerCase()}`;
62877
63001
  }
@@ -62888,8 +63012,8 @@ function journalLocation(context) {
62888
63012
  const attachment = context.branchAttachment ?? resolveBranchAttachment(context.workspaceRoot);
62889
63013
  if ("error" in attachment)
62890
63014
  return null;
62891
- const storeDirectory = path51.join(attachment.storePath, JOURNAL_DIRECTORY);
62892
- const fallback = path51.join(path51.resolve(context.workspaceRoot), ".kb", "recovery", JOURNAL_DIRECTORY, branchStoreKey(attachment.kbBranch));
63015
+ const storeDirectory = path52.join(attachment.storePath, JOURNAL_DIRECTORY);
63016
+ const fallback = path52.join(path52.resolve(context.workspaceRoot), ".kb", "recovery", JOURNAL_DIRECTORY, branchStoreKey(attachment.kbBranch));
62893
63017
  let storeReady = false;
62894
63018
  try {
62895
63019
  storeReady = statSync10(attachment.storePath).isDirectory() && existsSync26(branchStoreManifestPath(attachment.storePath));
@@ -62915,7 +63039,7 @@ function fsyncDirectory(directory) {
62915
63039
  } catch {}
62916
63040
  }
62917
63041
  function writeJournal(journalPath, journal) {
62918
- const directory = path51.dirname(journalPath);
63042
+ const directory = path52.dirname(journalPath);
62919
63043
  mkdirSync8(directory, { recursive: true, mode: 448 });
62920
63044
  const temporary = `${journalPath}.tmp-${process.pid}-${randomUUID3()}`;
62921
63045
  try {
@@ -62945,7 +63069,7 @@ function isFileWrite(value) {
62945
63069
  const entry = value;
62946
63070
  const before = entry.before;
62947
63071
  const after = entry.after;
62948
- return typeof entry.path === "string" && entry.path !== "" && !path51.isAbsolute(entry.path) && !entry.path.split(/[\\/]/).includes("..") && (entry.origin === "plan" || entry.origin === "entity-document" || entry.origin === "relationship-shard") && (entry.mode === "write" || entry.mode === "delete") && (before === null ? entry.beforeHash === null : typeof before === "string" && entry.beforeHash === contentHash(before)) && (after === null ? entry.afterHash === null : typeof after === "string" && entry.afterHash === contentHash(after)) && entry.mode === "delete" === (after === null);
63072
+ return typeof entry.path === "string" && entry.path !== "" && !path52.isAbsolute(entry.path) && !entry.path.split(/[\\/]/).includes("..") && (entry.origin === "plan" || entry.origin === "entity-document" || entry.origin === "relationship-shard") && (entry.mode === "write" || entry.mode === "delete") && (before === null ? entry.beforeHash === null : typeof before === "string" && entry.beforeHash === contentHash(before)) && (after === null ? entry.afterHash === null : typeof after === "string" && entry.afterHash === contentHash(after)) && entry.mode === "delete" === (after === null);
62949
63073
  }
62950
63074
  function parseJournal(journalId, text) {
62951
63075
  const parsed = JSON.parse(text);
@@ -62965,10 +63089,10 @@ function unrecoverableJournal(journalPath, detail) {
62965
63089
  throw new OperationError("PARTIAL_COMMIT_REPAIR_REQUIRED", `Plan application journal ${journalPath} cannot be recovered automatically: ${detail}. Kibi will not apply or recover plans on this branch until it is resolved: restore each listed file to its journaled before or after bytes and retry, or reconcile the workspace and branch store by hand (kibi sync) and remove the journal`, false);
62966
63090
  }
62967
63091
  function readJournalFile(journalPath) {
62968
- const journalId = path51.basename(journalPath, ".json");
63092
+ const journalId = path52.basename(journalPath, ".json");
62969
63093
  let text;
62970
63094
  try {
62971
- text = readFileSync27(journalPath, "utf8");
63095
+ text = readFileSync28(journalPath, "utf8");
62972
63096
  } catch (error) {
62973
63097
  unrecoverableJournal(journalPath, `unreadable (${errorText(error)})`);
62974
63098
  }
@@ -62985,9 +63109,9 @@ function openPlanApplyJournal(context, planHash) {
62985
63109
  }
62986
63110
  const journalId = planApplyJournalId(planHash);
62987
63111
  let existing = null;
62988
- let journalPath = path51.join(location.primary, `${journalId}.json`);
63112
+ let journalPath = path52.join(location.primary, `${journalId}.json`);
62989
63113
  for (const directory of location.all) {
62990
- const candidate = path51.join(directory, `${journalId}.json`);
63114
+ const candidate = path52.join(directory, `${journalId}.json`);
62991
63115
  if (existsSync26(candidate)) {
62992
63116
  existing = readJournalFile(candidate);
62993
63117
  journalPath = candidate;
@@ -63028,7 +63152,7 @@ async function currentHash(fsPort, absolute) {
63028
63152
  }
63029
63153
  }
63030
63154
  async function publishWorkspaceFile(fsPort, absolute, content) {
63031
- await fsPort.mkdir(path51.dirname(absolute));
63155
+ await fsPort.mkdir(path52.dirname(absolute));
63032
63156
  if (fsPort.rename) {
63033
63157
  const staged = `${absolute}.kibi-stage-${process.pid}-${randomUUID3()}`;
63034
63158
  try {
@@ -63049,7 +63173,7 @@ async function publishWorkspaceFile(fsPort, absolute, content) {
63049
63173
  await fsPort.fsync(absolute);
63050
63174
  }
63051
63175
  if (fsPort.fsync)
63052
- await fsPort.fsync(path51.dirname(absolute)).catch(() => {
63176
+ await fsPort.fsync(path52.dirname(absolute)).catch(() => {
63053
63177
  return;
63054
63178
  });
63055
63179
  }
@@ -63064,12 +63188,12 @@ async function removeWorkspaceFile(fsPort, absolute, relative) {
63064
63188
  throw error;
63065
63189
  }
63066
63190
  if (fsPort.fsync)
63067
- await fsPort.fsync(path51.dirname(absolute)).catch(() => {
63191
+ await fsPort.fsync(path52.dirname(absolute)).catch(() => {
63068
63192
  return;
63069
63193
  });
63070
63194
  }
63071
63195
  async function setFile(fsPort, workspaceRoot, relative, content) {
63072
- const absolute = path51.resolve(workspaceRoot, relative);
63196
+ const absolute = path52.resolve(workspaceRoot, relative);
63073
63197
  if (content === null)
63074
63198
  await removeWorkspaceFile(fsPort, absolute, relative);
63075
63199
  else
@@ -63084,7 +63208,7 @@ async function moveJournaledFiles(fsPort, workspaceRoot, journalPath, files, sid
63084
63208
  const pending = [];
63085
63209
  const conflicts = [];
63086
63210
  for (const file of files) {
63087
- const actual = await currentHash(fsPort, path51.resolve(workspaceRoot, file.path));
63211
+ const actual = await currentHash(fsPort, path52.resolve(workspaceRoot, file.path));
63088
63212
  const wanted = side === "before" ? file.beforeHash : file.afterHash;
63089
63213
  if (actual === wanted)
63090
63214
  continue;
@@ -63106,11 +63230,11 @@ async function moveJournaledFiles(fsPort, workspaceRoot, journalPath, files, sid
63106
63230
  }
63107
63231
  function removeOrphanedStagedFiles(workspaceRoot, files) {
63108
63232
  for (const file of files) {
63109
- const absolute = path51.resolve(workspaceRoot, file.path);
63110
- const prefix = `${path51.basename(absolute)}.kibi-stage-`;
63233
+ const absolute = path52.resolve(workspaceRoot, file.path);
63234
+ const prefix = `${path52.basename(absolute)}.kibi-stage-`;
63111
63235
  let names;
63112
63236
  try {
63113
- names = readdirSync8(path51.dirname(absolute));
63237
+ names = readdirSync8(path52.dirname(absolute));
63114
63238
  } catch {
63115
63239
  continue;
63116
63240
  }
@@ -63118,7 +63242,7 @@ function removeOrphanedStagedFiles(workspaceRoot, files) {
63118
63242
  if (!name.startsWith(prefix))
63119
63243
  continue;
63120
63244
  try {
63121
- unlinkSync5(path51.join(path51.dirname(absolute), name));
63245
+ unlinkSync5(path52.join(path52.dirname(absolute), name));
63122
63246
  } catch {}
63123
63247
  }
63124
63248
  }
@@ -63232,7 +63356,7 @@ function openPlanApplyJournalById(context, journalId) {
63232
63356
  throw new Error("Plan journal recovery failed: the KB branch could not be resolved");
63233
63357
  }
63234
63358
  for (const directory of location.all) {
63235
- const candidate = path51.join(directory, `${journalId}.json`);
63359
+ const candidate = path52.join(directory, `${journalId}.json`);
63236
63360
  if (existsSync26(candidate)) {
63237
63361
  return { journalPath: candidate, journal: readJournalFile(candidate) };
63238
63362
  }
@@ -63255,7 +63379,7 @@ async function recoverPendingPlanApplyJournals(context, options2) {
63255
63379
  }
63256
63380
  for (const name of names) {
63257
63381
  if (name.endsWith(".json") && isPlanApplyJournalId(name.slice(0, -5))) {
63258
- candidates.push(path51.join(directory, name));
63382
+ candidates.push(path52.join(directory, name));
63259
63383
  }
63260
63384
  }
63261
63385
  }
@@ -63322,10 +63446,10 @@ async function saveAtomicMutation(prolog, goals, operation) {
63322
63446
  }
63323
63447
 
63324
63448
  // ../cli/dist/operations/mutation/workspace-mutation-lock.js
63325
- import { mkdirSync as mkdirSync9, readFileSync as readFileSync28, renameSync as renameSync6, rmdirSync, unlinkSync as unlinkSync6, writeFileSync as writeFileSync8 } from "node:fs";
63326
- import * as path52 from "node:path";
63449
+ import { mkdirSync as mkdirSync9, readFileSync as readFileSync29, renameSync as renameSync6, rmdirSync, unlinkSync as unlinkSync6, writeFileSync as writeFileSync8 } from "node:fs";
63450
+ import * as path53 from "node:path";
63327
63451
  function lockPath(workspaceRoot, lockFileRelative) {
63328
- return path52.join(workspaceRoot, lockFileRelative);
63452
+ return path53.join(workspaceRoot, lockFileRelative);
63329
63453
  }
63330
63454
  function randomToken() {
63331
63455
  return `${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
@@ -63379,7 +63503,7 @@ function removeLockDirectory(fileSystem, target) {
63379
63503
  const result = retryTransientFilesystemOperation(() => fileSystem.rmdirSync(target));
63380
63504
  if (result.ok)
63381
63505
  return;
63382
- const ownerPath = path52.join(target, OWNER_FILE);
63506
+ const ownerPath = path53.join(target, OWNER_FILE);
63383
63507
  throw new WorkspaceMutationLockError(`failed to remove workspace mutation lock directory at ${target} after ${result.attempts} attempt(s): ${errorDetail(result.error)}; lock remains fail-closed. ${manualCleanupGuidance(target, ownerPath)}`);
63384
63508
  }
63385
63509
  function removeLockOwner(fileSystem, target, ownerPath, ignoreMissing) {
@@ -63450,7 +63574,7 @@ function reclaimDeadLock(fileSystem, target, holder, token) {
63450
63574
  return "changed";
63451
63575
  throw new WorkspaceMutationLockError(`failed to reclaim workspace mutation lock at ${target} from dead pid ${holder.pid}: ${errorDetail(error)}`);
63452
63576
  }
63453
- const tombstoneOwner = path52.join(tombstone, OWNER_FILE);
63577
+ const tombstoneOwner = path53.join(tombstone, OWNER_FILE);
63454
63578
  let moved = null;
63455
63579
  try {
63456
63580
  moved = readLockRecord(fileSystem.readFileSync(tombstoneOwner));
@@ -63511,10 +63635,10 @@ async function acquireWorkspaceMutationLock(workspaceRoot, options2 = {}) {
63511
63635
  const fileSystem = options2.fileSystem ?? NODE_FILE_SYSTEM;
63512
63636
  const isProcessAlive = options2.isProcessAlive ?? defaultIsProcessAlive;
63513
63637
  const target = lockPath(workspaceRoot, options2.lockFileRelative ?? DEFAULT_LOCK_FILE_RELATIVE);
63514
- const ownerPath = path52.join(target, OWNER_FILE);
63638
+ const ownerPath = path53.join(target, OWNER_FILE);
63515
63639
  const token = randomToken();
63516
63640
  const deadline = now() + timeoutMs;
63517
- const parentPath = path52.dirname(target);
63641
+ const parentPath = path53.dirname(target);
63518
63642
  const parentResult = retryTransientFilesystemOperation(() => fileSystem.mkdirSync(parentPath, { recursive: true }));
63519
63643
  if (!parentResult.ok) {
63520
63644
  throw new WorkspaceMutationLockError(`failed to create workspace mutation lock parent at ${parentPath} after ${parentResult.attempts} attempt(s): ${errorDetail(parentResult.error)}`);
@@ -63637,12 +63761,12 @@ async function acquireWorkspaceMutationLock(workspaceRoot, options2 = {}) {
63637
63761
  var DEFAULT_LOCK_FILE_RELATIVE, OWNER_FILE = "owner.json", DEFAULT_TIMEOUT_MS = 15000, RETRY_INTERVAL_MS = 25, MAX_RELEASE_FILESYSTEM_ATTEMPTS = 3, MAX_MISSING_OWNER_REREADS = 4, NODE_FILE_SYSTEM, WorkspaceMutationLockError;
63638
63762
  var init_workspace_mutation_lock = __esm(() => {
63639
63763
  init_cli_errors();
63640
- DEFAULT_LOCK_FILE_RELATIVE = path52.join(".kb", "recovery", "source-authoring.lock");
63764
+ DEFAULT_LOCK_FILE_RELATIVE = path53.join(".kb", "recovery", "source-authoring.lock");
63641
63765
  NODE_FILE_SYSTEM = {
63642
63766
  mkdirSync: (target, options2) => {
63643
63767
  mkdirSync9(target, options2);
63644
63768
  },
63645
- readFileSync: (target) => readFileSync28(target, "utf8"),
63769
+ readFileSync: (target) => readFileSync29(target, "utf8"),
63646
63770
  writeFileSync: (target, data, options2) => {
63647
63771
  writeFileSync8(target, data, options2);
63648
63772
  },
@@ -63657,8 +63781,8 @@ var init_workspace_mutation_lock = __esm(() => {
63657
63781
 
63658
63782
  // ../cli/dist/operations/mutation/delete.js
63659
63783
  import { createHash as createHash29, randomUUID as randomUUID4 } from "node:crypto";
63660
- import { existsSync as existsSync27, readFileSync as readFileSync29, writeFileSync as writeFileSync9 } from "node:fs";
63661
- import path53 from "node:path";
63784
+ import { existsSync as existsSync27, readFileSync as readFileSync30, writeFileSync as writeFileSync9 } from "node:fs";
63785
+ import path54 from "node:path";
63662
63786
  function requireProlog3(context) {
63663
63787
  if (context.prolog === undefined)
63664
63788
  throw new Error("Delete operation requires a Prolog runtime");
@@ -63694,7 +63818,7 @@ function sourceIsAuthored(source) {
63694
63818
  function fileHash(pathname) {
63695
63819
  if (!existsSync27(pathname))
63696
63820
  return null;
63697
- return createHash29("sha256").update(readFileSync29(pathname)).digest("hex");
63821
+ return createHash29("sha256").update(readFileSync30(pathname)).digest("hex");
63698
63822
  }
63699
63823
  async function executeRelationshipDeleteUnlocked(selectors, context, onCommitted = () => {
63700
63824
  return;
@@ -63710,7 +63834,7 @@ async function executeRelationshipDeleteUnlocked(selectors, context, onCommitted
63710
63834
  if (attachment.migrationRequired && (context.branchAttachment !== undefined || context.fs !== undefined)) {
63711
63835
  throw new Error(`Delete blocked: migrate legacy branch storage first with 'kibi branch migrate --from ${attachment.kbBranch} --to ${attachment.gitBranch} --apply'`);
63712
63836
  }
63713
- const shardRoot = path53.join(context.workspaceRoot, ".kb");
63837
+ const shardRoot = path54.join(context.workspaceRoot, ".kb");
63714
63838
  let shardRecords = [];
63715
63839
  try {
63716
63840
  shardRecords = readAllShards(shardRoot);
@@ -63789,7 +63913,7 @@ async function executeRelationshipDeleteUnlocked(selectors, context, onCommitted
63789
63913
  };
63790
63914
  const originalShardBytes = new Map(listShards(shardRoot).map((shardPath) => [
63791
63915
  shardPath,
63792
- readFileSync29(shardPath, "utf8")
63916
+ readFileSync30(shardPath, "utf8")
63793
63917
  ]));
63794
63918
  const originalShardHashes = new Map(listShards(shardRoot).map((shardPath) => [shardPath, fileHash(shardPath)]));
63795
63919
  let shardRemovals;
@@ -63808,7 +63932,7 @@ async function executeRelationshipDeleteUnlocked(selectors, context, onCommitted
63808
63932
  const writeSourcePatch = async (relative, body) => {
63809
63933
  assertFilesystemCapableRuntime(context.fs);
63810
63934
  const absolute = resolveContainedSourcePath(context.workspaceRoot, relative);
63811
- await context.fs.mkdir(path53.dirname(absolute));
63935
+ await context.fs.mkdir(path54.dirname(absolute));
63812
63936
  const temporary = `${absolute}.kibi-relationship-${process.pid}-${randomUUID4()}`;
63813
63937
  try {
63814
63938
  await context.fs.writeFile(temporary, body);
@@ -63873,7 +63997,7 @@ async function executeRelationshipDeleteUnlocked(selectors, context, onCommitted
63873
63997
  const after = fileHash(shardPath);
63874
63998
  if (before === after)
63875
63999
  return [];
63876
- const relative = path53.relative(context.workspaceRoot, shardPath).replaceAll("\\", "/");
64000
+ const relative = path54.relative(context.workspaceRoot, shardPath).replaceAll("\\", "/");
63877
64001
  if (after !== null) {
63878
64002
  writePendingSourceReceipt(context.workspaceRoot, relative, after);
63879
64003
  }
@@ -64009,7 +64133,7 @@ async function executeDelete(input, context) {
64009
64133
  authoredRequirementIds.push(id);
64010
64134
  if (context.fs) {
64011
64135
  const relativeSource = normalizeAuthoredSourcePath(context.workspaceRoot, source);
64012
- const sourcePath = path53.join(context.workspaceRoot, relativeSource);
64136
+ const sourcePath = path54.join(context.workspaceRoot, relativeSource);
64013
64137
  try {
64014
64138
  const original = sourceBodies.get(relativeSource) ?? await context.fs.readFile(sourcePath);
64015
64139
  if (!sourceBodies.has(relativeSource)) {
@@ -64041,12 +64165,12 @@ async function executeDelete(input, context) {
64041
64165
  if (authoredIds.length > 0 && context.sourcePlanApplication !== true) {
64042
64166
  if (context.fs) {
64043
64167
  const deleted = new Set(authoredIds);
64044
- for (const shardPath of listShards(path53.join(context.workspaceRoot, ".kb"))) {
64168
+ for (const shardPath of listShards(path54.join(context.workspaceRoot, ".kb"))) {
64045
64169
  const selectors = readShard(shardPath).filter((record) => deleted.has(record.from)).map(({ type, from, to }) => ({ type, from, to }));
64046
64170
  if (selectors.length === 0)
64047
64171
  continue;
64048
- const relativeShard = path53.relative(context.workspaceRoot, shardPath).replaceAll("\\", "/");
64049
- const original = readFileSync29(shardPath, "utf8");
64172
+ const relativeShard = path54.relative(context.workspaceRoot, shardPath).replaceAll("\\", "/");
64173
+ const original = readFileSync30(shardPath, "utf8");
64050
64174
  const body = renderShardWithout(original, selectors, shardPath);
64051
64175
  const beforeHash = createHash29("sha256").update(original).digest("hex");
64052
64176
  sourceHashes[relativeShard] = beforeHash;
@@ -64144,13 +64268,13 @@ var init_delete = __esm(() => {
64144
64268
  });
64145
64269
 
64146
64270
  // ../cli/dist/operations/mutation/context-warning.js
64147
- import { readFileSync as readFileSync30 } from "node:fs";
64148
- import path54 from "node:path";
64271
+ import { readFileSync as readFileSync31 } from "node:fs";
64272
+ import path55 from "node:path";
64149
64273
  function readBody(workspaceRoot, source) {
64150
64274
  if (typeof source !== "string" || !source.endsWith(".md"))
64151
64275
  return;
64152
64276
  try {
64153
- return readAuthoredEntity(readFileSync30(path54.resolve(workspaceRoot, source), "utf8"), source)?.body ?? undefined;
64277
+ return readAuthoredEntity(readFileSync31(path55.resolve(workspaceRoot, source), "utf8"), source)?.body ?? undefined;
64154
64278
  } catch {
64155
64279
  return;
64156
64280
  }
@@ -64190,7 +64314,7 @@ var init_context_warning = __esm(() => {
64190
64314
  });
64191
64315
 
64192
64316
  // ../cli/dist/operations/mutation/symbol-granularity.js
64193
- import path55 from "node:path";
64317
+ import path56 from "node:path";
64194
64318
  import { collectGranularityCandidates } from "kibi-plugin-builtin";
64195
64319
  function candidate(name, kind) {
64196
64320
  return { name, kind, role: inferSymbolRole(kind) };
@@ -64215,7 +64339,7 @@ async function validateSymbolGranularity(entity, relationships, context) {
64215
64339
  const fs = context.fs;
64216
64340
  if (fs === undefined)
64217
64341
  return;
64218
- const sourcePath = path55.isAbsolute(entity.sourceFile) ? entity.sourceFile : path55.resolve(context.workspaceRoot, entity.sourceFile);
64342
+ const sourcePath = path56.isAbsolute(entity.sourceFile) ? entity.sourceFile : path56.resolve(context.workspaceRoot, entity.sourceFile);
64219
64343
  let content;
64220
64344
  try {
64221
64345
  const stat = await fs.stat(sourcePath);
@@ -64547,10 +64671,10 @@ var init_saga = __esm(() => {
64547
64671
  });
64548
64672
 
64549
64673
  // ../cli/dist/operations/mutation/symbol-compiler-lock.js
64550
- import { mkdirSync as mkdirSync10, readFileSync as readFileSync31, rmdirSync as rmdirSync2, unlinkSync as unlinkSync7, writeFileSync as writeFileSync10 } from "node:fs";
64551
- import * as path56 from "node:path";
64674
+ import { mkdirSync as mkdirSync10, readFileSync as readFileSync32, rmdirSync as rmdirSync2, unlinkSync as unlinkSync7, writeFileSync as writeFileSync10 } from "node:fs";
64675
+ import * as path57 from "node:path";
64552
64676
  function lockPath2(workspaceRoot) {
64553
- return path56.join(workspaceRoot, LOCK_FILE_RELATIVE);
64677
+ return path57.join(workspaceRoot, LOCK_FILE_RELATIVE);
64554
64678
  }
64555
64679
  function randomToken2() {
64556
64680
  return `${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
@@ -64604,7 +64728,7 @@ function removeLockDirectory2(fileSystem, target) {
64604
64728
  const result = retryTransientFilesystemOperation2(() => fileSystem.rmdirSync(target));
64605
64729
  if (result.ok)
64606
64730
  return;
64607
- const ownerPath = path56.join(target, OWNER_FILE2);
64731
+ const ownerPath = path57.join(target, OWNER_FILE2);
64608
64732
  throw new SymbolCompilerLockError(`failed to remove symbol compiler lock directory at ${target} after ${result.attempts} attempt(s): ${errorDetail2(result.error)}; lock remains fail-closed. ${manualCleanupGuidance2(target, ownerPath)}`);
64609
64733
  }
64610
64734
  function removeLockOwner2(fileSystem, target, ownerPath, ignoreMissing) {
@@ -64693,10 +64817,10 @@ async function acquireSymbolCompilerLock(workspaceRoot, options2 = {}) {
64693
64817
  const fileSystem = options2.fileSystem ?? NODE_FILE_SYSTEM2;
64694
64818
  const isProcessAlive = options2.isProcessAlive ?? defaultIsProcessAlive2;
64695
64819
  const target = lockPath2(workspaceRoot);
64696
- const ownerPath = path56.join(target, OWNER_FILE2);
64820
+ const ownerPath = path57.join(target, OWNER_FILE2);
64697
64821
  const token = randomToken2();
64698
64822
  const deadline = now() + timeoutMs;
64699
- const parentPath = path56.dirname(target);
64823
+ const parentPath = path57.dirname(target);
64700
64824
  const parentResult = retryTransientFilesystemOperation2(() => fileSystem.mkdirSync(parentPath, { recursive: true }));
64701
64825
  if (!parentResult.ok) {
64702
64826
  throw new SymbolCompilerLockError(`failed to create symbol compiler lock parent at ${parentPath} after ${parentResult.attempts} attempt(s): ${errorDetail2(parentResult.error)}`);
@@ -64799,12 +64923,12 @@ async function withSymbolCompilerLock(workspaceRoot, operation, options2 = {}) {
64799
64923
  var LOCK_FILE_RELATIVE, OWNER_FILE2 = "owner.json", DEFAULT_TIMEOUT_MS2 = 15000, RETRY_INTERVAL_MS2 = 25, MAX_RELEASE_FILESYSTEM_ATTEMPTS2 = 3, NODE_FILE_SYSTEM2, SymbolCompilerLockError;
64800
64924
  var init_symbol_compiler_lock = __esm(() => {
64801
64925
  init_cli_errors();
64802
- LOCK_FILE_RELATIVE = path56.join(".kb", ".symbol-compiler.lock");
64926
+ LOCK_FILE_RELATIVE = path57.join(".kb", ".symbol-compiler.lock");
64803
64927
  NODE_FILE_SYSTEM2 = {
64804
64928
  mkdirSync: (target, options2) => {
64805
64929
  mkdirSync10(target, options2);
64806
64930
  },
64807
- readFileSync: (target) => readFileSync31(target, "utf8"),
64931
+ readFileSync: (target) => readFileSync32(target, "utf8"),
64808
64932
  writeFileSync: (target, data, options2) => {
64809
64933
  writeFileSync10(target, data, options2);
64810
64934
  },
@@ -64818,7 +64942,7 @@ var init_symbol_compiler_lock = __esm(() => {
64818
64942
 
64819
64943
  // ../cli/dist/extractors/symbols-coordinator.js
64820
64944
  import * as fs7 from "node:fs";
64821
- import * as path57 from "node:path";
64945
+ import * as path58 from "node:path";
64822
64946
  function analyzeSourceText(filePathOrEntries, contentOrWorkspaceRoot, optionsOrDeps) {
64823
64947
  if (Array.isArray(filePathOrEntries)) {
64824
64948
  return enrichSymbolCoordinates(filePathOrEntries, contentOrWorkspaceRoot, optionsOrDeps);
@@ -64859,13 +64983,13 @@ async function enrichSymbolCoordinates(entries, workspaceRoot, deps) {
64859
64983
  const resolved = resolveSourcePath(entry.sourceFile, workspaceRoot);
64860
64984
  if (!resolved || !fs7.statSync(resolved.absolutePath).isFile())
64861
64985
  continue;
64862
- const ext = path57.extname(resolved.absolutePath).toLowerCase();
64986
+ const ext = path58.extname(resolved.absolutePath).toLowerCase();
64863
64987
  if (isTsJsSourcePath(resolved.absolutePath)) {
64864
64988
  tsIndices.push(index);
64865
64989
  tsEntries.push(entry);
64866
64990
  continue;
64867
64991
  }
64868
- const logicalPath = path57.relative(workspaceRoot, resolved.absolutePath).replaceAll("\\", "/");
64992
+ const logicalPath = path58.relative(workspaceRoot, resolved.absolutePath).replaceAll("\\", "/");
64869
64993
  let analysis = analyses.get(logicalPath);
64870
64994
  const firstAnalysis = analysis === undefined;
64871
64995
  if (!analysis) {
@@ -64954,7 +65078,7 @@ function enrichWithRegexHeuristic(entry, absolutePath) {
64954
65078
  function resolveSourcePath(sourceFile, workspaceRoot) {
64955
65079
  if (!sourceFile)
64956
65080
  return null;
64957
- const absolutePath = path57.isAbsolute(sourceFile) ? sourceFile : path57.resolve(workspaceRoot, sourceFile);
65081
+ const absolutePath = path58.isAbsolute(sourceFile) ? sourceFile : path58.resolve(workspaceRoot, sourceFile);
64958
65082
  if (!fs7.existsSync(absolutePath))
64959
65083
  return null;
64960
65084
  return { absolutePath };
@@ -64981,9 +65105,9 @@ function detectSourceLanguage2(filePath) {
64981
65105
  return extensionLanguage(filePath);
64982
65106
  }
64983
65107
  function inferModuleTitle2(filePath) {
64984
- const extension = path57.extname(filePath);
64985
- const basename = path57.basename(filePath, extension);
64986
- return basename.length > 0 ? basename : path57.basename(filePath);
65108
+ const extension = path58.extname(filePath);
65109
+ const basename = path58.basename(filePath, extension);
65110
+ return basename.length > 0 ? basename : path58.basename(filePath);
64987
65111
  }
64988
65112
  var DEFAULT_SOURCE_ANALYSIS_PROVIDERS;
64989
65113
  var init_symbols_coordinator = __esm(() => {
@@ -65003,8 +65127,8 @@ var init_symbols_coordinator2 = __esm(() => {
65003
65127
 
65004
65128
  // ../cli/dist/operations/mutation/symbol-refresh.js
65005
65129
  import { createHash as createHash30, randomUUID as randomUUID5 } from "node:crypto";
65006
- import { existsSync as existsSync29, readFileSync as readFileSync33, renameSync as renameSync7, unlinkSync as unlinkSync8, writeFileSync as writeFileSync11 } from "node:fs";
65007
- import * as path58 from "node:path";
65130
+ import { existsSync as existsSync29, readFileSync as readFileSync34, renameSync as renameSync7, unlinkSync as unlinkSync8, writeFileSync as writeFileSync11 } from "node:fs";
65131
+ import * as path59 from "node:path";
65008
65132
  function record2(value) {
65009
65133
  return typeof value === "object" && value !== null && !Array.isArray(value);
65010
65134
  }
@@ -65015,15 +65139,15 @@ function coordinate(value) {
65015
65139
  return typeof sourceFile === "string" && typeof sourceLine === "number" && typeof sourceColumn === "number" && typeof sourceEndLine === "number" && typeof sourceEndColumn === "number" ? { sourceFile, sourceLine, sourceColumn, sourceEndLine, sourceEndColumn } : null;
65016
65140
  }
65017
65141
  async function manifestPath(context) {
65018
- return path58.join(context.workspaceRoot, CANONICAL_ENTITY_PATHS.symbols);
65142
+ return path59.join(context.workspaceRoot, CANONICAL_ENTITY_PATHS.symbols);
65019
65143
  }
65020
65144
  function artifactPathFor(manifest) {
65021
- return path58.join(path58.dirname(manifest), "symbol-coordinates.yaml");
65145
+ return path59.join(path59.dirname(manifest), "symbol-coordinates.yaml");
65022
65146
  }
65023
65147
  function sourceTextFor(sourceFile, workspaceRoot) {
65024
- const absolute = path58.isAbsolute(sourceFile) ? sourceFile : path58.resolve(workspaceRoot, sourceFile);
65148
+ const absolute = path59.isAbsolute(sourceFile) ? sourceFile : path59.resolve(workspaceRoot, sourceFile);
65025
65149
  try {
65026
- return readFileSync33(absolute, "utf8");
65150
+ return readFileSync34(absolute, "utf8");
65027
65151
  } catch {
65028
65152
  return null;
65029
65153
  }
@@ -65051,7 +65175,7 @@ function replaceArtifactAtomically(targetPath, content) {
65051
65175
  }
65052
65176
  }
65053
65177
  function publishArtifact(targetPath, content) {
65054
- const before = existsSync29(targetPath) ? readFileSync33(targetPath, "utf8") : null;
65178
+ const before = existsSync29(targetPath) ? readFileSync34(targetPath, "utf8") : null;
65055
65179
  const beforeHash = before === null ? null : contentHash2(before);
65056
65180
  const afterHash = contentHash2(content);
65057
65181
  replaceArtifactAtomically(targetPath, content);
@@ -65063,7 +65187,7 @@ function publishArtifact(targetPath, content) {
65063
65187
  if (!existsSync29(targetPath)) {
65064
65188
  throw new CoordinateArtifactError(`coordinate artifact disappeared before rollback: ${targetPath}`);
65065
65189
  }
65066
- const current = readFileSync33(targetPath, "utf8");
65190
+ const current = readFileSync34(targetPath, "utf8");
65067
65191
  if (contentHash2(current) !== afterHash) {
65068
65192
  throw new CoordinateArtifactError(`coordinate artifact changed after publication; refusing rollback: ${targetPath}`);
65069
65193
  }
@@ -65230,8 +65354,8 @@ var init_warnings = () => {};
65230
65354
 
65231
65355
  // ../cli/dist/operations/mutation/upsert.js
65232
65356
  import { createHash as createHash31 } from "node:crypto";
65233
- import { existsSync as existsSync30, readFileSync as readFileSync34, unlinkSync as unlinkSync9, writeFileSync as writeFileSync12 } from "node:fs";
65234
- import path59 from "node:path";
65357
+ import { existsSync as existsSync30, readFileSync as readFileSync35, unlinkSync as unlinkSync9, writeFileSync as writeFileSync12 } from "node:fs";
65358
+ import path60 from "node:path";
65235
65359
  function requireProlog4(context) {
65236
65360
  if (context.prolog === undefined) {
65237
65361
  throw new Error("Upsert operation requires a Prolog runtime");
@@ -65250,21 +65374,21 @@ function parseChangeKind(value) {
65250
65374
  function fileHash2(pathname) {
65251
65375
  if (!existsSync30(pathname))
65252
65376
  return null;
65253
- return createHash31("sha256").update(readFileSync34(pathname)).digest("hex");
65377
+ return createHash31("sha256").update(readFileSync35(pathname)).digest("hex");
65254
65378
  }
65255
65379
  function textHash(value) {
65256
65380
  return createHash31("sha256").update(value).digest("hex");
65257
65381
  }
65258
65382
  function assertRelationshipShardContained(workspaceRoot, shardPath) {
65259
- const root = path59.resolve(workspaceRoot);
65260
- const relationshipRoot = path59.resolve(root, ".kb", "relationships");
65261
- const absolute = path59.resolve(shardPath);
65262
- if (!absolute.startsWith(`${relationshipRoot}${path59.sep}`)) {
65383
+ const root = path60.resolve(workspaceRoot);
65384
+ const relationshipRoot = path60.resolve(root, ".kb", "relationships");
65385
+ const absolute = path60.resolve(shardPath);
65386
+ if (!absolute.startsWith(`${relationshipRoot}${path60.sep}`)) {
65263
65387
  throw new OperationError("SOURCE_PATH_INVALID", `Relationship shard escapes the canonical workspace lane: ${shardPath}`);
65264
65388
  }
65265
65389
  const realRoot = canonicalFilesystemPath(root);
65266
65390
  const real = canonicalFilesystemPath(absolute);
65267
- if (real !== realRoot && !real.startsWith(`${realRoot}${path59.sep}`)) {
65391
+ if (real !== realRoot && !real.startsWith(`${realRoot}${path60.sep}`)) {
65268
65392
  throw new OperationError("SOURCE_PATH_INVALID", `Relationship shard follows a symlink outside the workspace: ${shardPath}`);
65269
65393
  }
65270
65394
  }
@@ -65277,7 +65401,7 @@ function restoreRelationshipShard(shardPath, before, expectedAfterHash) {
65277
65401
  currentHash = null;
65278
65402
  }
65279
65403
  if (currentHash !== expectedAfterHash) {
65280
- console.warn(`Skipped relationship shard rollback for ${path59.relative(process.cwd(), shardPath)}: shard changed after the Kibi write.`);
65404
+ console.warn(`Skipped relationship shard rollback for ${path60.relative(process.cwd(), shardPath)}: shard changed after the Kibi write.`);
65281
65405
  return;
65282
65406
  }
65283
65407
  }
@@ -65327,7 +65451,7 @@ async function effectiveRelationships(input, entity, relationships, context, sta
65327
65451
  }
65328
65452
  }
65329
65453
  function reextractCanonicalSymbolEntity(symbolId, authoredRelativePath, workspaceRoot) {
65330
- const absoluteManifest = path59.resolve(workspaceRoot, authoredRelativePath);
65454
+ const absoluteManifest = path60.resolve(workspaceRoot, authoredRelativePath);
65331
65455
  let records;
65332
65456
  try {
65333
65457
  records = readManifestWithCoordinateOverlay(absoluteManifest);
@@ -65463,12 +65587,12 @@ async function executeUpsert(input, context, options2 = {}) {
65463
65587
  const to = typeof relationship.to === "string" ? relationship.to : "";
65464
65588
  if (!type || !from || !to)
65465
65589
  continue;
65466
- const shardPath = computeShardPath(path59.join(context.workspaceRoot, ".kb"), from);
65590
+ const shardPath = computeShardPath(path60.join(context.workspaceRoot, ".kb"), from);
65467
65591
  assertRelationshipShardContained(context.workspaceRoot, shardPath);
65468
65592
  if (!relationshipShardBefore.has(shardPath)) {
65469
- relationshipShardBefore.set(shardPath, existsSync30(shardPath) ? readFileSync34(shardPath, "utf8") : null);
65593
+ relationshipShardBefore.set(shardPath, existsSync30(shardPath) ? readFileSync35(shardPath, "utf8") : null);
65470
65594
  }
65471
- appendRelationship(path59.join(context.workspaceRoot, ".kb"), {
65595
+ appendRelationship(path60.join(context.workspaceRoot, ".kb"), {
65472
65596
  type,
65473
65597
  from,
65474
65598
  to,
@@ -65480,7 +65604,7 @@ async function executeUpsert(input, context, options2 = {}) {
65480
65604
  }
65481
65605
  }
65482
65606
  if (input.type === "symbol" && context.fs !== undefined && context.sourceFirst !== false && sourceWrite !== null) {
65483
- const refresh = await refreshSymbolCoordinatesForManifest(input.id, path59.resolve(context.workspaceRoot, sourceWrite.receipt.path), context);
65607
+ const refresh = await refreshSymbolCoordinatesForManifest(input.id, path60.resolve(context.workspaceRoot, sourceWrite.receipt.path), context);
65484
65608
  const coordinatePublication = refresh.publication;
65485
65609
  if (coordinatePublication !== undefined) {
65486
65610
  saga.add({
@@ -65581,14 +65705,14 @@ async function executeUpsert(input, context, options2 = {}) {
65581
65705
  const expectedAfterHash = relationshipShardAfterHash.get(shardPath) ?? null;
65582
65706
  if (afterHash === null) {
65583
65707
  if (expectedAfterHash !== null) {
65584
- const relative = path59.relative(context.workspaceRoot, shardPath).replaceAll("\\", "/");
65708
+ const relative = path60.relative(context.workspaceRoot, shardPath).replaceAll("\\", "/");
65585
65709
  shardWarnings.push(`Relationship shard vanished after write: ${relative}`);
65586
65710
  }
65587
65711
  continue;
65588
65712
  }
65589
65713
  if (afterHash === beforeHash)
65590
65714
  continue;
65591
- const relative = path59.relative(context.workspaceRoot, shardPath).replaceAll("\\", "/");
65715
+ const relative = path60.relative(context.workspaceRoot, shardPath).replaceAll("\\", "/");
65592
65716
  writePendingSourceReceipt(context.workspaceRoot, relative, afterHash);
65593
65717
  relationshipSourceWrites.push({
65594
65718
  path: relative,
@@ -66433,15 +66557,15 @@ function formatSyncSummary(summary) {
66433
66557
  }
66434
66558
 
66435
66559
  // ../cli/dist/commands/sync/manifest.js
66436
- import { existsSync as existsSync31, readFileSync as readFileSync35, renameSync as renameSync8, unlinkSync as unlinkSync10, writeFileSync as writeFileSync13 } from "node:fs";
66437
- import * as path60 from "node:path";
66560
+ import { existsSync as existsSync31, readFileSync as readFileSync36, renameSync as renameSync8, unlinkSync as unlinkSync10, writeFileSync as writeFileSync13 } from "node:fs";
66561
+ import * as path61 from "node:path";
66438
66562
  function resolveDeps2(overrides) {
66439
66563
  return {
66440
66564
  dumpYAML: dump,
66441
66565
  enrichSymbolCoordinates,
66442
66566
  existsSync: existsSync31,
66443
66567
  parseYAML: load,
66444
- readFileSync: readFileSync35,
66568
+ readFileSync: readFileSync36,
66445
66569
  renameSync: renameSync8,
66446
66570
  unlinkSync: unlinkSync10,
66447
66571
  writeFileSync: writeFileSync13,
@@ -66465,7 +66589,7 @@ function extractedCoordinates(entry) {
66465
66589
  } : null;
66466
66590
  }
66467
66591
  function readSourceText(sourceFile, workspaceRoot, deps) {
66468
- const absolute = path60.isAbsolute(sourceFile) ? sourceFile : path60.resolve(workspaceRoot, sourceFile);
66592
+ const absolute = path61.isAbsolute(sourceFile) ? sourceFile : path61.resolve(workspaceRoot, sourceFile);
66469
66593
  if (!deps.existsSync(absolute))
66470
66594
  return null;
66471
66595
  try {
@@ -66618,9 +66742,9 @@ async function refreshManifestCoordinates(manifestPath, workspaceRoot, deps) {
66618
66742
  if (!deps?.quiet) {
66619
66743
  const counts = `(refreshed=${refreshed}, unchanged=${unchanged}, failed=${failures.length})`;
66620
66744
  if (coordinatesPath !== null) {
66621
- console.log(`✓ Refreshed symbol coordinates in ${path60.relative(workspaceRoot, coordinatesPath)} ${counts}`);
66745
+ console.log(`✓ Refreshed symbol coordinates in ${path61.relative(workspaceRoot, coordinatesPath)} ${counts}`);
66622
66746
  } else {
66623
- console.log(`✓ Normalized symbol manifest ${path60.relative(workspaceRoot, manifestPath)} ${counts}`);
66747
+ console.log(`✓ Normalized symbol manifest ${path61.relative(workspaceRoot, manifestPath)} ${counts}`);
66624
66748
  }
66625
66749
  const maxReportedFailures = 10;
66626
66750
  for (const failure of failures.slice(0, maxReportedFailures)) {
@@ -66641,7 +66765,7 @@ function isEligibleForCoordinateRefresh(sourceFile, workspaceRoot, deps) {
66641
66765
  const resolved = resolveDeps2(deps);
66642
66766
  if (!sourceFile)
66643
66767
  return false;
66644
- const absolute = path60.isAbsolute(sourceFile) ? sourceFile : path60.resolve(workspaceRoot, sourceFile);
66768
+ const absolute = path61.isAbsolute(sourceFile) ? sourceFile : path61.resolve(workspaceRoot, sourceFile);
66645
66769
  return resolved.existsSync(absolute);
66646
66770
  }
66647
66771
  function isRecord16(value) {
@@ -66683,8 +66807,8 @@ var init_manifest3 = __esm(() => {
66683
66807
 
66684
66808
  // ../cli/dist/commands/sync/untracked-targets.js
66685
66809
  import { execFileSync as execFileSync7 } from "node:child_process";
66686
- import { existsSync as existsSync32, readFileSync as readFileSync36 } from "node:fs";
66687
- import * as path61 from "node:path";
66810
+ import { existsSync as existsSync32, readFileSync as readFileSync37 } from "node:fs";
66811
+ import * as path62 from "node:path";
66688
66812
  function findUntrackedDocumentMatches(workspaceRoot, missingIds, deps = {}) {
66689
66813
  const resolved = { ...defaultDeps3, ...deps };
66690
66814
  const matches = new Map;
@@ -66712,7 +66836,7 @@ function findUntrackedDocumentMatches(workspaceRoot, missingIds, deps = {}) {
66712
66836
  break;
66713
66837
  if (!relative.endsWith(".md"))
66714
66838
  continue;
66715
- const absolute = path61.resolve(workspaceRoot, relative.replaceAll("\\", "/"));
66839
+ const absolute = path62.resolve(workspaceRoot, relative.replaceAll("\\", "/"));
66716
66840
  if (!resolved.existsSync(absolute))
66717
66841
  continue;
66718
66842
  let content;
@@ -66723,7 +66847,7 @@ function findUntrackedDocumentMatches(workspaceRoot, missingIds, deps = {}) {
66723
66847
  }
66724
66848
  const id = frontmatterId(content);
66725
66849
  if (id !== null && remaining.has(id)) {
66726
- const workspaceRelative = path61.relative(workspaceRoot, absolute).replaceAll("\\", "/");
66850
+ const workspaceRelative = path62.relative(workspaceRoot, absolute).replaceAll("\\", "/");
66727
66851
  matches.set(id, workspaceRelative);
66728
66852
  remaining.delete(id);
66729
66853
  }
@@ -66751,12 +66875,12 @@ var init_untracked_targets = __esm(() => {
66751
66875
  defaultDeps3 = {
66752
66876
  execFileSync: (file, args, options2) => execFileSync7(file, args, options2),
66753
66877
  existsSync: existsSync32,
66754
- readFileSync: readFileSync36
66878
+ readFileSync: readFileSync37
66755
66879
  };
66756
66880
  });
66757
66881
 
66758
66882
  // ../cli/dist/commands/sync/persistence.js
66759
- import * as path62 from "node:path";
66883
+ import * as path63 from "node:path";
66760
66884
  function getEntityField(entity, field) {
66761
66885
  return entity[field];
66762
66886
  }
@@ -66834,8 +66958,8 @@ function sourceLookupCandidates(sourceFile) {
66834
66958
  return [
66835
66959
  ...new Set([
66836
66960
  sourceFile,
66837
- path62.relative(process.cwd(), sourceFile),
66838
- path62.basename(sourceFile)
66961
+ path63.relative(process.cwd(), sourceFile),
66962
+ path63.basename(sourceFile)
66839
66963
  ])
66840
66964
  ];
66841
66965
  }
@@ -67123,7 +67247,7 @@ async function persistEntities(prolog, results, entityIds, options2 = {}) {
67123
67247
  return { entityCount, kbModified };
67124
67248
  }
67125
67249
  function semanticEntityContext(entity, sourceFile) {
67126
- const displaySource = path62.isAbsolute(sourceFile) ? path62.relative(process.cwd(), sourceFile) : sourceFile;
67250
+ const displaySource = path63.isAbsolute(sourceFile) ? path63.relative(process.cwd(), sourceFile) : sourceFile;
67127
67251
  const details = [`source=${displaySource}`];
67128
67252
  if (entity.type === "fact") {
67129
67253
  const factKind = getEntityField(entity, "fact_kind");
@@ -67144,7 +67268,7 @@ async function persistRelationships(prolog, results, shardRelationships, options
67144
67268
  let kbModified = false;
67145
67269
  const idLookup = new Map;
67146
67270
  for (const { entity } of results) {
67147
- const filename = path62.basename(entity.source, ".md");
67271
+ const filename = path63.basename(entity.source, ".md");
67148
67272
  idLookup.set(filename, entity.id);
67149
67273
  idLookup.set(entity.id, entity.id);
67150
67274
  }
@@ -67342,7 +67466,7 @@ var init_persistence = __esm(() => {
67342
67466
  // ../cli/dist/commands/sync/staging.js
67343
67467
  import { existsSync as existsSync33, mkdirSync as mkdirSync11, renameSync as renameSync9, rmSync as rmSync4, writeFileSync as writeFileSync14 } from "node:fs";
67344
67468
  import { copyFileSync as copyFileSync2 } from "node:fs";
67345
- import * as path63 from "node:path";
67469
+ import * as path64 from "node:path";
67346
67470
  function resolveDeps3(overrides) {
67347
67471
  return {
67348
67472
  copyCleanSnapshot,
@@ -67367,15 +67491,15 @@ function resolveDeps3(overrides) {
67367
67491
  };
67368
67492
  }
67369
67493
  function createUniqueStagingPath(currentBranch, rootDir, pid = process.pid, now = Date.now()) {
67370
- return path63.join(rootDir, ".kb", "branches", `${currentBranch}.staging.${pid}.${now}`);
67494
+ return path64.join(rootDir, ".kb", "branches", `${currentBranch}.staging.${pid}.${now}`);
67371
67495
  }
67372
67496
  function abandonedStagingBranch(branch) {
67373
67497
  return branch ? branch : undefined;
67374
67498
  }
67375
67499
  async function cleanupAbandonedStagingDirectories(stagingPath, deps) {
67376
67500
  const resolved = resolveDeps3(deps);
67377
- const stagingDir = path63.dirname(stagingPath);
67378
- const stagingBase = path63.basename(stagingPath);
67501
+ const stagingDir = path64.dirname(stagingPath);
67502
+ const stagingBase = path64.basename(stagingPath);
67379
67503
  const match = /^(?<branch>.*)\.staging\.(?<pid>\d+)\.(?<timestamp>\d+)$/.exec(stagingBase);
67380
67504
  if (!match?.groups) {
67381
67505
  return;
@@ -67394,7 +67518,7 @@ async function cleanupAbandonedStagingDirectories(stagingPath, deps) {
67394
67518
  if (candidate === stagingPath) {
67395
67519
  continue;
67396
67520
  }
67397
- const candidateBase = path63.basename(candidate);
67521
+ const candidateBase = path64.basename(candidate);
67398
67522
  const candidateMatch = new RegExp(`^${escapeRegex2(branch)}\\.staging\\.(\\d+)\\.(\\d+)$`).exec(candidateBase);
67399
67523
  if (!candidateMatch) {
67400
67524
  continue;
@@ -67420,25 +67544,25 @@ async function prepareStagingEnvironment(stagingPath, livePath, rebuild, deps) {
67420
67544
  } else {
67421
67545
  await copySchemaToStaging(stagingPath, resolved);
67422
67546
  }
67423
- const markerPath = path63.join(stagingPath, "storage.json");
67547
+ const markerPath = path64.join(stagingPath, "storage.json");
67424
67548
  const canWriteMetadata = deps === undefined || deps.writeFileSync !== undefined;
67425
67549
  if (canWriteMetadata && resolved.existsSync(stagingPath) && !resolved.existsSync(markerPath)) {
67426
- resolved.mkdirSync(path63.join(stagingPath, "rdf"), { recursive: true });
67550
+ resolved.mkdirSync(path64.join(stagingPath, "rdf"), { recursive: true });
67427
67551
  resolved.writeFileSync(markerPath, `{"format":"kibi.rdf-journal.v1","schemaVersion":1}
67428
67552
  `, { mode: 384 });
67429
67553
  const generation = rebuild ? `generation-${process.pid}-${Date.now()}` : "generation-1";
67430
- resolved.writeFileSync(path63.join(stagingPath, "CURRENT"), `${generation}:0
67554
+ resolved.writeFileSync(path64.join(stagingPath, "CURRENT"), `${generation}:0
67431
67555
  `, { mode: 384 });
67432
- resolved.writeFileSync(path63.join(stagingPath, "kb.rdf"), `KIBI_STORAGE_FORMAT=kibi.rdf-journal.v1
67556
+ resolved.writeFileSync(path64.join(stagingPath, "kb.rdf"), `KIBI_STORAGE_FORMAT=kibi.rdf-journal.v1
67433
67557
  `, { mode: 384 });
67434
67558
  }
67435
67559
  }
67436
67560
  async function copySchemaToStaging(stagingPath, deps) {
67437
67561
  const possibleSchemaPaths = [
67438
- path63.resolve(deps.cwd(), "node_modules", "kibi-cli", "schema"),
67439
- path63.resolve(deps.cwd(), "..", "..", "schema"),
67440
- path63.resolve(deps.moduleDir, "..", "..", "schema"),
67441
- path63.resolve(deps.cwd(), "packages", "cli", "schema")
67562
+ path64.resolve(deps.cwd(), "node_modules", "kibi-cli", "schema"),
67563
+ path64.resolve(deps.cwd(), "..", "..", "schema"),
67564
+ path64.resolve(deps.moduleDir, "..", "..", "schema"),
67565
+ path64.resolve(deps.cwd(), "packages", "cli", "schema")
67442
67566
  ];
67443
67567
  let schemaSourceDir = null;
67444
67568
  for (const p of possibleSchemaPaths) {
@@ -67454,19 +67578,19 @@ async function copySchemaToStaging(stagingPath, deps) {
67454
67578
  cwd: schemaSourceDir,
67455
67579
  absolute: false
67456
67580
  });
67457
- const schemaDestDir = path63.join(stagingPath, "schema");
67581
+ const schemaDestDir = path64.join(stagingPath, "schema");
67458
67582
  if (!deps.existsSync(schemaDestDir)) {
67459
67583
  deps.mkdirSync(schemaDestDir, { recursive: true });
67460
67584
  }
67461
67585
  for (const file of schemaFiles) {
67462
- const sourcePath = path63.join(schemaSourceDir, file);
67463
- const destPath = path63.join(schemaDestDir, file);
67586
+ const sourcePath = path64.join(schemaSourceDir, file);
67587
+ const destPath = path64.join(schemaDestDir, file);
67464
67588
  deps.copyFileSync(sourcePath, destPath);
67465
67589
  }
67466
67590
  }
67467
67591
  function atomicPublish(stagingPath, livePath, deps) {
67468
67592
  const resolved = resolveDeps3(deps);
67469
- const liveParent = path63.dirname(livePath);
67593
+ const liveParent = path64.dirname(livePath);
67470
67594
  if (!resolved.existsSync(liveParent)) {
67471
67595
  resolved.mkdirSync(liveParent, { recursive: true });
67472
67596
  }
@@ -67481,7 +67605,7 @@ function atomicPublish(stagingPath, livePath, deps) {
67481
67605
  }
67482
67606
  function atomicPublishGeneration(stagingPath, livePath, deps) {
67483
67607
  const resolved = resolveDeps3(deps);
67484
- const liveParent = path63.dirname(livePath);
67608
+ const liveParent = path64.dirname(livePath);
67485
67609
  if (!resolved.existsSync(liveParent)) {
67486
67610
  resolved.mkdirSync(liveParent, { recursive: true });
67487
67611
  }
@@ -67490,11 +67614,11 @@ function atomicPublishGeneration(stagingPath, livePath, deps) {
67490
67614
  return;
67491
67615
  }
67492
67616
  const generationStamp = `${Date.now()}.${process.pid}`;
67493
- const liveRdf = path63.join(livePath, "rdf");
67494
- const stagedRdf = path63.join(stagingPath, "rdf");
67617
+ const liveRdf = path64.join(livePath, "rdf");
67618
+ const stagedRdf = path64.join(stagingPath, "rdf");
67495
67619
  const oldRdf = `${liveRdf}.old.${generationStamp}`;
67496
- const liveCurrent = path63.join(livePath, "CURRENT");
67497
- const stagedCurrent = path63.join(stagingPath, "CURRENT");
67620
+ const liveCurrent = path64.join(livePath, "CURRENT");
67621
+ const stagedCurrent = path64.join(stagingPath, "CURRENT");
67498
67622
  const oldCurrent = `${liveCurrent}.old.${generationStamp}`;
67499
67623
  if (!resolved.existsSync(stagedRdf) || !resolved.existsSync(stagedCurrent)) {
67500
67624
  throw new Error("Rebuilt journal generation is missing rdf or CURRENT");
@@ -67548,8 +67672,8 @@ var init_staging = __esm(() => {
67548
67672
  // ../cli/dist/commands/sync.js
67549
67673
  import { execSync as execSync4 } from "node:child_process";
67550
67674
  import { createHash as createHash32 } from "node:crypto";
67551
- import { existsSync as existsSync34, mkdirSync as mkdirSync12, readFileSync as readFileSync37, readdirSync as readdirSync9, renameSync as renameSync10, writeFileSync as writeFileSync15 } from "node:fs";
67552
- import * as path64 from "node:path";
67675
+ import { existsSync as existsSync34, mkdirSync as mkdirSync12, readFileSync as readFileSync38, readdirSync as readdirSync9, renameSync as renameSync10, writeFileSync as writeFileSync15 } from "node:fs";
67676
+ import * as path65 from "node:path";
67553
67677
  function relationshipKey2(relationship) {
67554
67678
  return `${relationship.type}\x00${relationship.from}\x00${relationship.to}`;
67555
67679
  }
@@ -67591,14 +67715,14 @@ function trackedRelationshipFiles(workspaceRoot, relationshipsDir, recoverMissin
67591
67715
  return [];
67592
67716
  }
67593
67717
  const pending = new Set;
67594
- const pendingRoot = path64.join(workspaceRoot, ".kb", "recovery", "pending-sources");
67718
+ const pendingRoot = path65.join(workspaceRoot, ".kb", "recovery", "pending-sources");
67595
67719
  if (existsSync34(pendingRoot)) {
67596
67720
  for (const receiptName of readdirSync9(pendingRoot)) {
67597
67721
  if (!receiptName.endsWith(".json"))
67598
67722
  continue;
67599
67723
  let receipt;
67600
67724
  try {
67601
- receipt = JSON.parse(readFileSync37(path64.join(pendingRoot, receiptName), "utf8"));
67725
+ receipt = JSON.parse(readFileSync38(path65.join(pendingRoot, receiptName), "utf8"));
67602
67726
  } catch {
67603
67727
  continue;
67604
67728
  }
@@ -67608,26 +67732,26 @@ function trackedRelationshipFiles(workspaceRoot, relationshipsDir, recoverMissin
67608
67732
  const relative = receipt.path.replaceAll("\\", "/");
67609
67733
  if (!relative.startsWith(".kb/relationships/"))
67610
67734
  continue;
67611
- const absolute = path64.resolve(workspaceRoot, relative);
67612
- if (!absolute.startsWith(`${path64.resolve(workspaceRoot)}${path64.sep}`)) {
67735
+ const absolute = path65.resolve(workspaceRoot, relative);
67736
+ if (!absolute.startsWith(`${path65.resolve(workspaceRoot)}${path65.sep}`)) {
67613
67737
  throw new SyncError(`Pending source path escapes workspace: ${relative}`);
67614
67738
  }
67615
67739
  if (!existsSync34(absolute)) {
67616
67740
  if (recoverMissingPendingSources) {
67617
- const receiptPath = path64.join(pendingRoot, receiptName);
67741
+ const receiptPath = path65.join(pendingRoot, receiptName);
67618
67742
  if (!recoveredPendingReceiptPaths.some((candidate) => candidate.receiptPath === receiptPath)) {
67619
67743
  recoveredPendingReceiptPaths.push({
67620
67744
  receiptPath,
67621
67745
  path: relative,
67622
67746
  afterHash: receipt.afterHash,
67623
- rawHash: createHash32("sha256").update(readFileSync37(receiptPath)).digest("hex")
67747
+ rawHash: createHash32("sha256").update(readFileSync38(receiptPath)).digest("hex")
67624
67748
  });
67625
67749
  }
67626
67750
  continue;
67627
67751
  }
67628
67752
  throw new SyncError(`Pending source is missing: ${relative}.${PENDING_SOURCE_RECOVERY_HINT}`);
67629
67753
  }
67630
- const actual = createHash32("sha256").update(readFileSync37(absolute)).digest("hex");
67754
+ const actual = createHash32("sha256").update(readFileSync38(absolute)).digest("hex");
67631
67755
  if (actual !== receipt.afterHash) {
67632
67756
  throw new SyncError(`Pending source hash drift blocks sync for ${relative}`);
67633
67757
  }
@@ -67635,8 +67759,8 @@ function trackedRelationshipFiles(workspaceRoot, relationshipsDir, recoverMissin
67635
67759
  }
67636
67760
  }
67637
67761
  try {
67638
- return readdirSync9(relationshipsDir).filter((file) => file.endsWith(".yaml") || file.endsWith(".yml")).map((file) => path64.join(relationshipsDir, file)).filter((file) => {
67639
- const relative = path64.relative(workspaceRoot, file).replaceAll(path64.sep, "/");
67762
+ return readdirSync9(relationshipsDir).filter((file) => file.endsWith(".yaml") || file.endsWith(".yml")).map((file) => path65.join(relationshipsDir, file)).filter((file) => {
67763
+ const relative = path65.relative(workspaceRoot, file).replaceAll(path65.sep, "/");
67640
67764
  return tracked.has(relative) || pending.has(relative);
67641
67765
  }).sort();
67642
67766
  } catch {
@@ -67740,7 +67864,7 @@ async function syncCommand(options2 = {}, runtime = {}) {
67740
67864
  } : (...args) => console.log(...args);
67741
67865
  const rebuild = options2.rebuild ?? false;
67742
67866
  const recoveryBackupPath = options2.recoveryBackupPath;
67743
- const workspaceRoot = path64.resolve(options2.workspaceRoot ?? process.cwd());
67867
+ const workspaceRoot = path65.resolve(options2.workspaceRoot ?? process.cwd());
67744
67868
  const startTime = Date.now();
67745
67869
  const diagnostics = [];
67746
67870
  const entityCounts = {};
@@ -67824,7 +67948,7 @@ async function syncCommand(options2 = {}, runtime = {}) {
67824
67948
  console.log("[kibi-debug] manifestFiles:", manifestFiles.length);
67825
67949
  }
67826
67950
  const sourceFiles = [...markdownFiles, ...manifestFiles].sort();
67827
- const cachePath = path64.join(livePathForEngine, "sync-cache.json");
67951
+ const cachePath = path65.join(livePathForEngine, "sync-cache.json");
67828
67952
  const syncCache = readSyncCache(cachePath, undefined, {
67829
67953
  compilerFingerprint: SYNC_COMPILER_FINGERPRINT
67830
67954
  });
@@ -67832,7 +67956,7 @@ async function syncCommand(options2 = {}, runtime = {}) {
67832
67956
  const nowMs = Date.now();
67833
67957
  const currentSourceKeys = new Set(sourceFiles.map((file) => toCacheKey(workspaceRoot, file)));
67834
67958
  const relationshipShardFiles = existsSync34(relationshipsDir) ? trackedRelationshipFiles(workspaceRoot, relationshipsDir, recoveryBackupPath !== undefined, recoveredPendingReceiptPaths) : [];
67835
- const fastPathSourceHashOf = (file) => manifestFiles.includes(file) ? hashManifestWithCoordinates(workspaceRoot, file, path64.join(path64.dirname(file), "symbol-coordinates.yaml")) : hashFile(workspaceRoot, file);
67959
+ const fastPathSourceHashOf = (file) => manifestFiles.includes(file) ? hashManifestWithCoordinates(workspaceRoot, file, path65.join(path65.dirname(file), "symbol-coordinates.yaml")) : hashFile(workspaceRoot, file);
67836
67960
  if (!validateOnly && !rebuild && !options2.refreshSymbolCoordinates && runtime.createProlog === undefined && compilerCacheHasEntityDelta(syncCache) && compilerCacheIsFresh(syncCache, workspaceRoot, sourceFiles, nowMs) && compilerCacheFilesMatch(syncCache, workspaceRoot, sourceFiles, relationshipShardFiles, fastPathSourceHashOf)) {
67837
67961
  await checkpointNoopSync(workspaceRoot, currentBranch);
67838
67962
  info("✓ Imported 0 entities, 0 relationships (no changes)");
@@ -67857,7 +67981,7 @@ async function syncCommand(options2 = {}, runtime = {}) {
67857
67981
  refreshedManifestKeys.add(toCacheKey(workspaceRoot, file));
67858
67982
  }
67859
67983
  }
67860
- const coordinatesPathForManifest = (manifestFile) => path64.join(path64.dirname(manifestFile), "symbol-coordinates.yaml");
67984
+ const coordinatesPathForManifest = (manifestFile) => path65.join(path65.dirname(manifestFile), "symbol-coordinates.yaml");
67861
67985
  const effectiveSourceHash = (file) => manifestFiles.includes(file) ? hashManifestWithCoordinates(workspaceRoot, file, coordinatesPathForManifest(file)) : hashFile(workspaceRoot, file);
67862
67986
  const changedSourceHashes = new Map;
67863
67987
  for (const file of sourceFiles) {
@@ -67882,7 +68006,7 @@ async function syncCommand(options2 = {}, runtime = {}) {
67882
68006
  const changedMarkdownFiles = [];
67883
68007
  const changedManifestFiles = [];
67884
68008
  const forceEntitySourceKeys = new Set;
67885
- const deletedSourceFiles = Object.keys(syncCache.hashes).filter((key) => !currentSourceKeys.has(key)).map((key) => path64.resolve(workspaceRoot, key));
68009
+ const deletedSourceFiles = Object.keys(syncCache.hashes).filter((key) => !currentSourceKeys.has(key)).map((key) => path65.resolve(workspaceRoot, key));
67886
68010
  const currentRelationshipKeys = new Set;
67887
68011
  for (const shardPath of relationshipShardFiles) {
67888
68012
  const key = toCacheKey(workspaceRoot, shardPath);
@@ -68226,7 +68350,7 @@ async function syncCommand(options2 = {}, runtime = {}) {
68226
68350
  evictedSemanticContracts[key] = nextSemanticContracts[key] === true;
68227
68351
  }
68228
68352
  }
68229
- writeSyncCache(path64.join(livePath, "sync-cache.json"), {
68353
+ writeSyncCache(path65.join(livePath, "sync-cache.json"), {
68230
68354
  version: SYNC_CACHE_VERSION,
68231
68355
  hashes: evictedHashes,
68232
68356
  relationshipHashes: nextRelationshipHashes,
@@ -68353,7 +68477,7 @@ async function syncCommand(options2 = {}, runtime = {}) {
68353
68477
  }
68354
68478
  await prolog.query("kb_detach");
68355
68479
  await prolog.terminate();
68356
- const journaledLive = existsSync34(path64.join(livePath, "storage.json"));
68480
+ const journaledLive = existsSync34(path65.join(livePath, "storage.json"));
68357
68481
  if (recoveryBackupPath !== undefined) {
68358
68482
  if (!existsSync34(livePath)) {
68359
68483
  throw new SyncError(`Recovery target disappeared before publication: ${livePath}`);
@@ -68361,7 +68485,7 @@ async function syncCommand(options2 = {}, runtime = {}) {
68361
68485
  if (existsSync34(recoveryBackupPath)) {
68362
68486
  throw new SyncError(`Recovery backup path already exists: ${recoveryBackupPath}`);
68363
68487
  }
68364
- mkdirSync12(path64.dirname(recoveryBackupPath), { recursive: true });
68488
+ mkdirSync12(path65.dirname(recoveryBackupPath), { recursive: true });
68365
68489
  renameSync10(livePath, recoveryBackupPath);
68366
68490
  try {
68367
68491
  renameSync10(stagingPath, livePath);
@@ -68397,7 +68521,7 @@ async function syncCommand(options2 = {}, runtime = {}) {
68397
68521
  evictedSemanticContracts[key] = nextSemanticContracts[key] === true;
68398
68522
  }
68399
68523
  }
68400
- const liveCachePath = path64.join(livePath, "sync-cache.json");
68524
+ const liveCachePath = path65.join(livePath, "sync-cache.json");
68401
68525
  writeSyncCache(liveCachePath, {
68402
68526
  version: SYNC_CACHE_VERSION,
68403
68527
  hashes: evictedHashes,
@@ -68490,7 +68614,7 @@ var init_sync = __esm(() => {
68490
68614
  // ../cli/dist/commands/branch.js
68491
68615
  import { createHash as createHash33 } from "node:crypto";
68492
68616
  import * as fs8 from "node:fs";
68493
- import * as path65 from "node:path";
68617
+ import * as path66 from "node:path";
68494
68618
  function isSupportedLegacyBranchMigration(from, to) {
68495
68619
  return from === to;
68496
68620
  }
@@ -68498,12 +68622,12 @@ function hashLegacyStore(sourcePath) {
68498
68622
  const hash = createHash33("sha256");
68499
68623
  const visit = (directory, relative = "") => {
68500
68624
  for (const entry of fs8.readdirSync(directory, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name))) {
68501
- const absolute = path65.join(directory, entry.name);
68502
- const child = relative ? path65.join(relative, entry.name) : entry.name;
68625
+ const absolute = path66.join(directory, entry.name);
68626
+ const child = relative ? path66.join(relative, entry.name) : entry.name;
68503
68627
  if (entry.isDirectory())
68504
68628
  visit(absolute, child);
68505
68629
  else if (entry.isFile()) {
68506
- hash.update(child.replaceAll(path65.sep, "/"));
68630
+ hash.update(child.replaceAll(path66.sep, "/"));
68507
68631
  hash.update("\x00");
68508
68632
  hash.update(fs8.readFileSync(absolute));
68509
68633
  hash.update("\x00");
@@ -68529,7 +68653,7 @@ function migrationJournalPath(workspaceRoot, id) {
68529
68653
  if (!/^[A-Za-z0-9._-]+$/.test(id)) {
68530
68654
  throw new Error("branch migration journal ID is invalid");
68531
68655
  }
68532
- return path65.join(workspaceRoot, ".kb", "recovery", "branch-migrations", `${id}.json`);
68656
+ return path66.join(workspaceRoot, ".kb", "recovery", "branch-migrations", `${id}.json`);
68533
68657
  }
68534
68658
  function writeMigrationJournal(journalPath, journal) {
68535
68659
  fs8.writeFileSync(journalPath, `${JSON.stringify(journal, null, 2)}
@@ -68549,9 +68673,9 @@ function recoverBranchMigration(workspaceRoot, id, apply) {
68549
68673
  const journal = JSON.parse(fs8.readFileSync(journalPath, "utf8"));
68550
68674
  if (journal.version !== 2)
68551
68675
  throw new Error("Unsupported branch migration journal version");
68552
- const root = path65.resolve(workspaceRoot);
68553
- const paths = ["sourcePath", "targetPath", "stagingPath", "backupPath"].map((key) => path65.resolve(root, String(journal[key])));
68554
- if (paths.some((candidate) => !candidate.startsWith(`${root}${path65.sep}`))) {
68676
+ const root = path66.resolve(workspaceRoot);
68677
+ const paths = ["sourcePath", "targetPath", "stagingPath", "backupPath"].map((key) => path66.resolve(root, String(journal[key])));
68678
+ if (paths.some((candidate) => !candidate.startsWith(`${root}${path66.sep}`))) {
68555
68679
  throw new Error("Branch migration journal path escapes workspace");
68556
68680
  }
68557
68681
  const [sourcePath, targetPath, stagingPath, backupPath] = completeBranchJournalPaths(paths);
@@ -68604,7 +68728,7 @@ function createEmptyBranchKb(branch, workspaceRoot) {
68604
68728
  console.log(`Created branch KB: ${branch} (${kbPath})`);
68605
68729
  }
68606
68730
  async function branchEnsureCommand(options2) {
68607
- const workspaceRoot = path65.resolve(options2?.workspaceRoot ?? process.cwd());
68731
+ const workspaceRoot = path66.resolve(options2?.workspaceRoot ?? process.cwd());
68608
68732
  const branchResult = resolveBranchAttachment(workspaceRoot);
68609
68733
  if ("error" in branchResult) {
68610
68734
  console.error(getBranchDiagnostic(undefined, branchResult.error));
@@ -68625,7 +68749,7 @@ async function branchEnsureCommand(options2) {
68625
68749
  createEmptyBranchKb(currentBranch, workspaceRoot);
68626
68750
  }
68627
68751
  async function branchMigrateCommand(options2 = {}) {
68628
- const workspaceRoot = path65.resolve(options2.workspaceRoot ?? process.cwd());
68752
+ const workspaceRoot = path66.resolve(options2.workspaceRoot ?? process.cwd());
68629
68753
  if (options2.recoverJournal !== undefined) {
68630
68754
  recoverBranchMigration(workspaceRoot, options2.recoverJournal, options2.apply === true);
68631
68755
  return;
@@ -68699,18 +68823,18 @@ async function branchMigrateCommand(options2 = {}) {
68699
68823
  }
68700
68824
  fs8.mkdirSync(root, { recursive: true });
68701
68825
  const migrationId = `${Date.now()}-${from.replaceAll("/", "__")}-${to.replaceAll("/", "__")}`;
68702
- const journalPath = path65.join(workspaceRoot, ".kb", "recovery", "branch-migrations", `${migrationId}.json`);
68826
+ const journalPath = path66.join(workspaceRoot, ".kb", "recovery", "branch-migrations", `${migrationId}.json`);
68703
68827
  const stagingPath = `${targetPath}.staging-${process.pid}-${Date.now()}`;
68704
- const backupPath = path65.join(workspaceRoot, ".kb", "recovery", "branch-migrations", `${migrationId}-legacy`);
68705
- fs8.mkdirSync(path65.dirname(backupPath), { recursive: true });
68828
+ const backupPath = path66.join(workspaceRoot, ".kb", "recovery", "branch-migrations", `${migrationId}-legacy`);
68829
+ fs8.mkdirSync(path66.dirname(backupPath), { recursive: true });
68706
68830
  const journal = {
68707
68831
  version: 2,
68708
68832
  from,
68709
68833
  to,
68710
- sourcePath: path65.relative(workspaceRoot, sourcePath),
68711
- targetPath: path65.relative(workspaceRoot, targetPath),
68712
- stagingPath: path65.relative(workspaceRoot, stagingPath),
68713
- backupPath: path65.relative(workspaceRoot, backupPath),
68834
+ sourcePath: path66.relative(workspaceRoot, sourcePath),
68835
+ targetPath: path66.relative(workspaceRoot, targetPath),
68836
+ stagingPath: path66.relative(workspaceRoot, stagingPath),
68837
+ backupPath: path66.relative(workspaceRoot, backupPath),
68714
68838
  approvalHash,
68715
68839
  state: "prepared"
68716
68840
  };
@@ -68747,7 +68871,7 @@ async function branchMigrateCommand(options2 = {}) {
68747
68871
  }
68748
68872
  }
68749
68873
  async function branchRecoverCommand(options2 = {}) {
68750
- const workspaceRoot = path65.resolve(options2.workspaceRoot ?? process.cwd());
68874
+ const workspaceRoot = path66.resolve(options2.workspaceRoot ?? process.cwd());
68751
68875
  const attachment = resolveBranchAttachment(workspaceRoot);
68752
68876
  if ("error" in attachment) {
68753
68877
  throw new Error(`Failed to resolve active branch: ${attachment.error}`);
@@ -68760,7 +68884,7 @@ async function branchRecoverCommand(options2 = {}) {
68760
68884
  throw new Error(`Branch KB is missing at ${inspection.path}; run 'kibi branch ensure' instead.`);
68761
68885
  }
68762
68886
  const stamp = new Date().toISOString().replaceAll(":", "-");
68763
- const backupPath = path65.join(workspaceRoot, ".kb", "recovery", attachment.kbBranch, stamp);
68887
+ const backupPath = path66.join(workspaceRoot, ".kb", "recovery", attachment.kbBranch, stamp);
68764
68888
  console.log(`Branch KB recovery preview: ${attachment.kbBranch}`);
68765
68889
  console.log(`Store: ${inspection.path}`);
68766
68890
  console.log(`State: ${inspection.state}${inspection.errorCode ? ` (${inspection.errorCode})` : ""}`);
@@ -68784,15 +68908,15 @@ async function branchRecoverCommand(options2 = {}) {
68784
68908
  if (!checkpoint.success) {
68785
68909
  throw new Error("Recovered branch KB could not establish a fresh checkpoint.");
68786
68910
  }
68787
- const auditPath = path65.join(workspaceRoot, ".kb", "migrations", `${attachment.kbBranch.replaceAll("/", "__")}.recovery.json`);
68788
- fs8.mkdirSync(path65.dirname(auditPath), { recursive: true });
68911
+ const auditPath = path66.join(workspaceRoot, ".kb", "migrations", `${attachment.kbBranch.replaceAll("/", "__")}.recovery.json`);
68912
+ fs8.mkdirSync(path66.dirname(auditPath), { recursive: true });
68789
68913
  fs8.writeFileSync(auditPath, `${JSON.stringify({
68790
68914
  version: 1,
68791
68915
  branch: attachment.kbBranch,
68792
68916
  recoveredAt: new Date().toISOString(),
68793
68917
  priorState: inspection.state,
68794
68918
  priorErrorCode: inspection.errorCode ?? null,
68795
- backupPath: path65.relative(workspaceRoot, backupPath),
68919
+ backupPath: path66.relative(workspaceRoot, backupPath),
68796
68920
  strategy: "rebuild_from_authored_sources"
68797
68921
  }, null, 2)}
68798
68922
  `, "utf8");
@@ -68809,7 +68933,7 @@ var init_branch = __esm(() => {
68809
68933
 
68810
68934
  // ../cli/dist/operations/migration/inventory-rederive.js
68811
68935
  import { createHash as createHash34 } from "node:crypto";
68812
- import path66 from "node:path";
68936
+ import path67 from "node:path";
68813
68937
  import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
68814
68938
  function isRecord17(value) {
68815
68939
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -68856,7 +68980,7 @@ class FactClaimIndex {
68856
68980
  this.workspaceRoot = workspaceRoot;
68857
68981
  }
68858
68982
  claimKey(factId) {
68859
- const direct = path66.join(this.workspaceRoot, KB_PATHS.lanes.facts, `${factId}.md`);
68983
+ const direct = path67.join(this.workspaceRoot, KB_PATHS.lanes.facts, `${factId}.md`);
68860
68984
  try {
68861
68985
  const result = extractFromMarkdown(direct);
68862
68986
  if (result.entity.id === factId)
@@ -69030,7 +69154,7 @@ function planOne(workspaceRoot, relativePath, entity, extracted, shards, facts)
69030
69154
  }
69031
69155
  function readShardRelationships(workspaceRoot) {
69032
69156
  try {
69033
- return readAllShards(path66.join(workspaceRoot, ".kb")).map(({ type, from, to }) => ({ type, from, to }));
69157
+ return readAllShards(path67.join(workspaceRoot, ".kb")).map(({ type, from, to }) => ({ type, from, to }));
69034
69158
  } catch {
69035
69159
  return [];
69036
69160
  }
@@ -69040,7 +69164,7 @@ function planInventoryRederivation(workspaceRoot, onlyId) {
69040
69164
  const facts = new FactClaimIndex(workspaceRoot);
69041
69165
  const plans = [];
69042
69166
  const files = listLaneMarkdownFiles(workspaceRoot, ["requirements"]);
69043
- const preferred = onlyId === undefined ? files : files.filter((file) => path66.basename(file.relativePath, ".md") === onlyId);
69167
+ const preferred = onlyId === undefined ? files : files.filter((file) => path67.basename(file.relativePath, ".md") === onlyId);
69044
69168
  for (const file of preferred.length > 0 ? preferred : files) {
69045
69169
  let result;
69046
69170
  try {
@@ -69137,7 +69261,7 @@ function applyInventoryRederivation(workspaceRoot, requirementId, expectedContra
69137
69261
  if (expectedContractHash !== undefined && plan.contractHash !== expectedContractHash) {
69138
69262
  throw new Error(`Requirement ${requirementId} changed since planning; rerun kibi migrate and approve the new plan.`);
69139
69263
  }
69140
- const absolute = path66.join(workspaceRoot, plan.path);
69264
+ const absolute = path67.join(workspaceRoot, plan.path);
69141
69265
  const content = readText(absolute);
69142
69266
  const next = content === null ? null : rewriteContract(content, plan.contract);
69143
69267
  if (next === null) {
@@ -69183,7 +69307,7 @@ var init_inventory_rederive = __esm(() => {
69183
69307
  });
69184
69308
 
69185
69309
  // ../cli/dist/operations/migration/origin-backfill.js
69186
- import path67 from "node:path";
69310
+ import path68 from "node:path";
69187
69311
  import { isDeepStrictEqual as isDeepStrictEqual4 } from "node:util";
69188
69312
  function isRecord18(value) {
69189
69313
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -69225,8 +69349,8 @@ function inspect(workspaceRoot, absolutePath, relativePath) {
69225
69349
  migrated: "origin" in origin && origin.origin.kind === "migration" && origin.origin.ref === SCHEMA6_MIGRATION_ORIGIN_REF
69226
69350
  };
69227
69351
  }
69228
- const id = typeof data.id === "string" && data.id.trim() !== "" ? data.id.trim() : path67.basename(relativePath, ".md");
69229
- const type = typeof data.type === "string" ? data.type : inferTypeFromPath(path67.join(workspaceRoot, relativePath)) ?? "";
69352
+ const id = typeof data.id === "string" && data.id.trim() !== "" ? data.id.trim() : path68.basename(relativePath, ".md");
69353
+ const type = typeof data.type === "string" ? data.type : inferTypeFromPath(path68.join(workspaceRoot, relativePath)) ?? "";
69230
69354
  return { kind: "target", target: { id, type, path: relativePath }, content };
69231
69355
  }
69232
69356
  function planOriginBackfill(workspaceRoot) {
@@ -69307,7 +69431,7 @@ var init_origin_backfill = __esm(() => {
69307
69431
  });
69308
69432
 
69309
69433
  // ../cli/dist/operations/migration/superseded-closure.js
69310
- import path68 from "node:path";
69434
+ import path69 from "node:path";
69311
69435
  function reachable(adjacency, start) {
69312
69436
  const seen = new Set;
69313
69437
  const queue = [...adjacency.get(start) ?? []];
@@ -69359,7 +69483,7 @@ function readRequirementsAndEdges(workspaceRoot) {
69359
69483
  } catch {}
69360
69484
  }
69361
69485
  try {
69362
- relationships.push(...readAllShards(path68.join(workspaceRoot, ".kb")));
69486
+ relationships.push(...readAllShards(path69.join(workspaceRoot, ".kb")));
69363
69487
  } catch {}
69364
69488
  const edges = new Map;
69365
69489
  for (const relationship of relationships) {
@@ -69415,7 +69539,7 @@ function applySupersededClosures(workspaceRoot, planned) {
69415
69539
  for (const closure of planSupersededClosures(workspaceRoot).closures) {
69416
69540
  if (planned !== undefined && !planned.has(closure.id))
69417
69541
  continue;
69418
- const absolute = path68.join(workspaceRoot, closure.path);
69542
+ const absolute = path69.join(workspaceRoot, closure.path);
69419
69543
  const content = readText(absolute);
69420
69544
  const next = content === null ? null : withTopLevelField(content, "status", CLOSED_REQUIREMENT_STATUS);
69421
69545
  if (next === null) {
@@ -69438,11 +69562,11 @@ var init_superseded_closure = __esm(() => {
69438
69562
  });
69439
69563
 
69440
69564
  // ../cli/dist/commands/init-helpers.js
69441
- import { constants as constants3, chmodSync as chmodSync2, copyFileSync as copyFileSync3, existsSync as existsSync36, lstatSync as lstatSync5, mkdirSync as mkdirSync14, readFileSync as readFileSync39, writeFileSync as writeFileSync17 } from "node:fs";
69442
- import * as path69 from "node:path";
69565
+ import { constants as constants3, chmodSync as chmodSync2, copyFileSync as copyFileSync3, existsSync as existsSync36, lstatSync as lstatSync5, mkdirSync as mkdirSync14, readFileSync as readFileSync40, writeFileSync as writeFileSync17 } from "node:fs";
69566
+ import * as path70 from "node:path";
69443
69567
  function updateGitIgnore(cwd) {
69444
- const gitignorePath = path69.join(cwd, ".gitignore");
69445
- const gitignoreContent = existsSync36(gitignorePath) ? readFileSync39(gitignorePath, "utf8") : "";
69568
+ const gitignorePath = path70.join(cwd, ".gitignore");
69569
+ const gitignoreContent = existsSync36(gitignorePath) ? readFileSync40(gitignorePath, "utf8") : "";
69446
69570
  const ensureEntry = (current, entry) => {
69447
69571
  const lines = current.split(/\r?\n/).map((line) => line.trim());
69448
69572
  if (lines.includes(entry)) {
@@ -69599,8 +69723,8 @@ ${KIBI_BIN_RESOLVER}
69599
69723
 
69600
69724
  // ../cli/dist/commands/legacy-storage-migration.js
69601
69725
  import { createHash as createHash35 } from "node:crypto";
69602
- import { existsSync as existsSync37, mkdirSync as mkdirSync15, readFileSync as readFileSync40, readdirSync as readdirSync11, renameSync as renameSync12, rmSync as rmSync5, statSync as statSync12, writeFileSync as writeFileSync18 } from "node:fs";
69603
- import * as path70 from "node:path";
69726
+ import { existsSync as existsSync37, mkdirSync as mkdirSync15, readFileSync as readFileSync41, readdirSync as readdirSync11, renameSync as renameSync12, rmSync as rmSync5, statSync as statSync12, writeFileSync as writeFileSync18 } from "node:fs";
69727
+ import * as path71 from "node:path";
69604
69728
  function stripGlobToRoot(pattern) {
69605
69729
  const normalized = pattern.replaceAll("\\", "/").replace(/\/+$/, "");
69606
69730
  if (!normalized.includes("*"))
@@ -69638,8 +69762,8 @@ function planLegacyStorageMigration(cwd) {
69638
69762
  if (typeof legacy !== "string" || legacy.trim().length === 0)
69639
69763
  continue;
69640
69764
  const { root, glob } = normalizeLegacySource(legacy);
69641
- const legacyRoot = path70.resolve(cwd, root);
69642
- if (legacyRoot === path70.resolve(cwd, KB_PATHS.lanes[lane]))
69765
+ const legacyRoot = path71.resolve(cwd, root);
69766
+ if (legacyRoot === path71.resolve(cwd, KB_PATHS.lanes[lane]))
69643
69767
  continue;
69644
69768
  if (!existsSync37(legacyRoot))
69645
69769
  continue;
@@ -69650,37 +69774,37 @@ function planLegacyStorageMigration(cwd) {
69650
69774
  onlyFiles: true
69651
69775
  });
69652
69776
  for (const file of files.sort()) {
69653
- const relativeUnderRoot = path70.relative(legacyRoot, file);
69654
- const destination = path70.join(cwd, KB_PATHS.lanes[lane], relativeUnderRoot);
69777
+ const relativeUnderRoot = path71.relative(legacyRoot, file);
69778
+ const destination = path71.join(cwd, KB_PATHS.lanes[lane], relativeUnderRoot);
69655
69779
  moves.push({
69656
- from: path70.relative(cwd, file).replaceAll(path70.sep, "/"),
69657
- to: path70.relative(cwd, destination).replaceAll(path70.sep, "/"),
69780
+ from: path71.relative(cwd, file).replaceAll(path71.sep, "/"),
69781
+ to: path71.relative(cwd, destination).replaceAll(path71.sep, "/"),
69658
69782
  lane
69659
69783
  });
69660
69784
  }
69661
69785
  }
69662
69786
  const legacySymbols = legacyPaths.symbols;
69663
69787
  if (typeof legacySymbols === "string" && legacySymbols.trim().length > 0) {
69664
- const legacyManifest = path70.resolve(cwd, legacySymbols);
69665
- if (existsSync37(legacyManifest) && legacyManifest !== path70.resolve(cwd, CANONICAL_ENTITY_PATHS.symbols)) {
69788
+ const legacyManifest = path71.resolve(cwd, legacySymbols);
69789
+ if (existsSync37(legacyManifest) && legacyManifest !== path71.resolve(cwd, CANONICAL_ENTITY_PATHS.symbols)) {
69666
69790
  moves.push({
69667
- from: path70.relative(cwd, legacyManifest).replaceAll(path70.sep, "/"),
69791
+ from: path71.relative(cwd, legacyManifest).replaceAll(path71.sep, "/"),
69668
69792
  to: CANONICAL_ENTITY_PATHS.symbols,
69669
69793
  lane: "symbols"
69670
69794
  });
69671
69795
  }
69672
69796
  const legacyCoordinates = legacySymbols.replace(/\.ya?ml$/, ".yaml").replace(/symbols\.yaml$/, "symbol-coordinates.yaml");
69673
- const legacyCoordinatesPath = path70.resolve(cwd, legacyCoordinates);
69674
- if (existsSync37(legacyCoordinatesPath) && legacyCoordinatesPath !== path70.resolve(cwd, KB_PATHS.symbolCoordinates)) {
69797
+ const legacyCoordinatesPath = path71.resolve(cwd, legacyCoordinates);
69798
+ if (existsSync37(legacyCoordinatesPath) && legacyCoordinatesPath !== path71.resolve(cwd, KB_PATHS.symbolCoordinates)) {
69675
69799
  moves.push({
69676
- from: path70.relative(cwd, legacyCoordinatesPath).replaceAll(path70.sep, "/"),
69800
+ from: path71.relative(cwd, legacyCoordinatesPath).replaceAll(path71.sep, "/"),
69677
69801
  to: KB_PATHS.symbolCoordinates,
69678
69802
  lane: "symbols"
69679
69803
  });
69680
69804
  }
69681
69805
  }
69682
69806
  for (const move of moves) {
69683
- const destinationAbsolute = path70.resolve(cwd, move.to);
69807
+ const destinationAbsolute = path71.resolve(cwd, move.to);
69684
69808
  if (!existsSync37(destinationAbsolute))
69685
69809
  continue;
69686
69810
  blockers.push(`Destination ${move.to} already exists; resolve the conflict manually before migrating ${move.from}.`);
@@ -69708,12 +69832,12 @@ function applyLegacyStorageMigration(cwd, plan) {
69708
69832
  }
69709
69833
  const movedFiles = [];
69710
69834
  for (const move of plan.moves) {
69711
- const sourceAbsolute = path70.resolve(cwd, move.from);
69712
- const destinationAbsolute = path70.resolve(cwd, move.to);
69835
+ const sourceAbsolute = path71.resolve(cwd, move.from);
69836
+ const destinationAbsolute = path71.resolve(cwd, move.to);
69713
69837
  if (!existsSync37(sourceAbsolute)) {
69714
69838
  continue;
69715
69839
  }
69716
- mkdirSync15(path70.dirname(destinationAbsolute), { recursive: true });
69840
+ mkdirSync15(path71.dirname(destinationAbsolute), { recursive: true });
69717
69841
  renameSync12(sourceAbsolute, destinationAbsolute);
69718
69842
  movedFiles.push(move.to);
69719
69843
  }
@@ -69727,7 +69851,7 @@ function applyLegacyStorageMigration(cwd, plan) {
69727
69851
  };
69728
69852
  const manifestPath = writeKbManifest(cwd, manifest);
69729
69853
  let retiredLegacyConfig = false;
69730
- const legacyConfigPath = path70.join(cwd, ".kb", "config.json");
69854
+ const legacyConfigPath = path71.join(cwd, ".kb", "config.json");
69731
69855
  if (existsSync37(legacyConfigPath)) {
69732
69856
  rmSync5(legacyConfigPath);
69733
69857
  retiredLegacyConfig = true;
@@ -69738,7 +69862,7 @@ function applyLegacyStorageMigration(cwd, plan) {
69738
69862
  return {
69739
69863
  movedFiles,
69740
69864
  retiredLegacyConfig,
69741
- manifestPath: path70.relative(cwd, manifestPath).replaceAll(path70.sep, "/"),
69865
+ manifestPath: path71.relative(cwd, manifestPath).replaceAll(path71.sep, "/"),
69742
69866
  schemaVersion: manifest.schemaVersion,
69743
69867
  semanticAdvisorBackfill: backfill
69744
69868
  };
@@ -69746,11 +69870,11 @@ function applyLegacyStorageMigration(cwd, plan) {
69746
69870
  function pruneEmptyLegacyDirs(cwd, plan) {
69747
69871
  const roots = new Set;
69748
69872
  for (const move of plan.moves) {
69749
- const absolute = path70.resolve(cwd, move.from);
69750
- let dir = path70.dirname(absolute);
69751
- while (dir.startsWith(path70.resolve(cwd)) && dir !== path70.resolve(cwd) && !dir.startsWith(path70.resolve(cwd, KB_ROOT2))) {
69873
+ const absolute = path71.resolve(cwd, move.from);
69874
+ let dir = path71.dirname(absolute);
69875
+ while (dir.startsWith(path71.resolve(cwd)) && dir !== path71.resolve(cwd) && !dir.startsWith(path71.resolve(cwd, KB_ROOT2))) {
69752
69876
  roots.add(dir);
69753
- dir = path70.dirname(dir);
69877
+ dir = path71.dirname(dir);
69754
69878
  }
69755
69879
  }
69756
69880
  const ordered = [...roots].sort((a, b) => b.length - a.length);
@@ -69763,7 +69887,7 @@ function pruneEmptyLegacyDirs(cwd, plan) {
69763
69887
  }
69764
69888
  }
69765
69889
  function rewritePendingSourceReceiptPaths(cwd, moves) {
69766
- const pendingRoot = path70.join(cwd, ".kb", "recovery", "pending-sources");
69890
+ const pendingRoot = path71.join(cwd, ".kb", "recovery", "pending-sources");
69767
69891
  if (!existsSync37(pendingRoot))
69768
69892
  return 0;
69769
69893
  const moveByFrom = new Map(moves.map((move) => [move.from, move.to]));
@@ -69771,9 +69895,9 @@ function rewritePendingSourceReceiptPaths(cwd, moves) {
69771
69895
  for (const name of readdirSync11(pendingRoot)) {
69772
69896
  if (!name.endsWith(".json"))
69773
69897
  continue;
69774
- const receiptPath = path70.join(pendingRoot, name);
69898
+ const receiptPath = path71.join(pendingRoot, name);
69775
69899
  try {
69776
- const raw = readFileSync40(receiptPath, "utf8");
69900
+ const raw = readFileSync41(receiptPath, "utf8");
69777
69901
  const receipt = JSON.parse(raw);
69778
69902
  if (typeof receipt.path !== "string")
69779
69903
  continue;
@@ -69781,10 +69905,10 @@ function rewritePendingSourceReceiptPaths(cwd, moves) {
69781
69905
  const destination = moveByFrom.get(normalized) ?? (normalized.startsWith("documentation/") ? normalized.replace(/^documentation\//, ".kb/") : undefined);
69782
69906
  if (destination === undefined || destination === normalized)
69783
69907
  continue;
69784
- const absolute = path70.resolve(cwd, destination);
69908
+ const absolute = path71.resolve(cwd, destination);
69785
69909
  if (!existsSync37(absolute))
69786
69910
  continue;
69787
- const afterHash = typeof receipt.afterHash === "string" && /^[a-f0-9]{64}$/i.test(receipt.afterHash) ? receipt.afterHash : createHash35("sha256").update(readFileSync40(absolute)).digest("hex");
69911
+ const afterHash = typeof receipt.afterHash === "string" && /^[a-f0-9]{64}$/i.test(receipt.afterHash) ? receipt.afterHash : createHash35("sha256").update(readFileSync41(absolute)).digest("hex");
69788
69912
  writeFileSync18(receiptPath, `${JSON.stringify({ ...receipt, path: destination, afterHash }, null, 2)}
69789
69913
  `, "utf8");
69790
69914
  rewritten += 1;
@@ -70325,26 +70449,26 @@ var require_ignore = __commonJS(function(exports2, module2) {
70325
70449
  });
70326
70450
 
70327
70451
  // ../cli/dist/public/ignore-policy.js
70328
- import { existsSync as existsSync38, readFileSync as readFileSync41, readdirSync as readdirSync12 } from "node:fs";
70329
- import * as path71 from "node:path";
70452
+ import { existsSync as existsSync38, readFileSync as readFileSync42, readdirSync as readdirSync12 } from "node:fs";
70453
+ import * as path72 from "node:path";
70330
70454
  function readIgnoreFileLines(filePath) {
70331
70455
  if (!existsSync38(filePath))
70332
70456
  return [];
70333
70457
  try {
70334
- const content = readFileSync41(filePath, "utf8");
70458
+ const content = readFileSync42(filePath, "utf8");
70335
70459
  return content.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0 && !l.startsWith("#"));
70336
70460
  } catch {
70337
70461
  return [];
70338
70462
  }
70339
70463
  }
70340
70464
  function toPosix(p) {
70341
- return p.split(path71.sep).join("/");
70465
+ return p.split(path72.sep).join("/");
70342
70466
  }
70343
70467
  function createRepoIgnorePolicy(workspaceRoot) {
70344
- const root = path71.resolve(workspaceRoot);
70345
- const rootGitignorePath = path71.join(root, ".gitignore");
70468
+ const root = path72.resolve(workspaceRoot);
70469
+ const rootGitignorePath = path72.join(root, ".gitignore");
70346
70470
  const rootGitPatterns = readIgnoreFileLines(rootGitignorePath);
70347
- const gitInfoExcludePath = path71.join(root, ".git", "info", "exclude");
70471
+ const gitInfoExcludePath = path72.join(root, ".git", "info", "exclude");
70348
70472
  const gitInfoPatterns = readIgnoreFileLines(gitInfoExcludePath);
70349
70473
  const nestedPatterns = new Map;
70350
70474
  function walk(dirAbs) {
@@ -70356,7 +70480,7 @@ function createRepoIgnorePolicy(workspaceRoot) {
70356
70480
  }
70357
70481
  for (const ent of entries) {
70358
70482
  const name = String(ent.name);
70359
- const abs = path71.join(dirAbs, name);
70483
+ const abs = path72.join(dirAbs, name);
70360
70484
  if (ent.isDirectory()) {
70361
70485
  if (HARD_DENYLIST.includes(name))
70362
70486
  continue;
@@ -70367,10 +70491,10 @@ function createRepoIgnorePolicy(workspaceRoot) {
70367
70491
  walk(abs);
70368
70492
  } else if (ent.isFile()) {
70369
70493
  if (name === ".gitignore") {
70370
- if (path71.resolve(dirAbs) === root)
70494
+ if (path72.resolve(dirAbs) === root)
70371
70495
  continue;
70372
70496
  const patterns = readIgnoreFileLines(abs);
70373
- const relDir = path71.relative(root, dirAbs) || ".";
70497
+ const relDir = path72.relative(root, dirAbs) || ".";
70374
70498
  nestedPatterns.set(toPosix(relDir), patterns);
70375
70499
  }
70376
70500
  }
@@ -70392,8 +70516,8 @@ function createRepoIgnorePolicy(workspaceRoot) {
70392
70516
  }
70393
70517
  const nestedDirsSorted = Array.from(nestedIgnoreMap.keys()).sort((a, b) => b.length - a.length);
70394
70518
  function isPathOutsideWorkspace(absPath) {
70395
- const rel = path71.relative(root, absPath);
70396
- return rel === "" ? false : rel.split(path71.sep)[0] === "..";
70519
+ const rel = path72.relative(root, absPath);
70520
+ return rel === "" ? false : rel.split(path72.sep)[0] === "..";
70397
70521
  }
70398
70522
  function matchesHardDeny(relPosix) {
70399
70523
  const segments = relPosix.split("/").filter(Boolean);
@@ -70409,11 +70533,11 @@ function createRepoIgnorePolicy(workspaceRoot) {
70409
70533
  return false;
70410
70534
  }
70411
70535
  function isIgnoredInternal(inputPath) {
70412
- const abs = path71.isAbsolute(inputPath) ? path71.resolve(inputPath) : path71.resolve(root, inputPath);
70413
- if (path71.isAbsolute(inputPath) && isPathOutsideWorkspace(abs)) {
70536
+ const abs = path72.isAbsolute(inputPath) ? path72.resolve(inputPath) : path72.resolve(root, inputPath);
70537
+ if (path72.isAbsolute(inputPath) && isPathOutsideWorkspace(abs)) {
70414
70538
  return { ignored: true, reason: "outside_workspace" };
70415
70539
  }
70416
- const rel = path71.relative(root, abs) || ".";
70540
+ const rel = path72.relative(root, abs) || ".";
70417
70541
  const relPosix = toPosix(rel);
70418
70542
  if (matchesHardDeny(relPosix))
70419
70543
  return { ignored: true, reason: "hard_deny" };
@@ -70524,7 +70648,7 @@ import { execFile as execFile2, execFileSync as execFileSync8 } from "node:child
70524
70648
  import { createHash as createHash36 } from "node:crypto";
70525
70649
  import * as fsSync from "node:fs";
70526
70650
  import * as fs9 from "node:fs/promises";
70527
- import path72 from "node:path";
70651
+ import path73 from "node:path";
70528
70652
  import { promisify as promisify2 } from "node:util";
70529
70653
  function includedSnapshotPath(relativePath) {
70530
70654
  return !SNAPSHOT_EXCLUDED_PREFIXES.some((prefix) => relativePath === prefix.slice(0, -1) || relativePath.startsWith(prefix));
@@ -70533,7 +70657,7 @@ function isReceiptOnlyMarkdownChange(workspaceRoot, relativePath) {
70533
70657
  if (!relativePath.endsWith(".md"))
70534
70658
  return false;
70535
70659
  try {
70536
- const working = snapshotFileContent(relativePath, fsSync.readFileSync(path72.join(workspaceRoot, relativePath)));
70660
+ const working = snapshotFileContent(relativePath, fsSync.readFileSync(path73.join(workspaceRoot, relativePath)));
70537
70661
  const committed = execFileSync8("git", ["-C", workspaceRoot, "show", `HEAD:${relativePath}`], { encoding: "buffer", maxBuffer: 64 * 1024 * 1024 });
70538
70662
  return working.equals(snapshotFileContent(relativePath, committed));
70539
70663
  } catch {
@@ -70557,7 +70681,7 @@ async function workspaceSnapshot(workspaceRoot) {
70557
70681
  digest.update(relativePath);
70558
70682
  digest.update("\x00");
70559
70683
  try {
70560
- const content = await fs9.readFile(path72.join(workspaceRoot, raw));
70684
+ const content = await fs9.readFile(path73.join(workspaceRoot, raw));
70561
70685
  digest.update(snapshotFileContent(relativePath, content));
70562
70686
  } catch (error) {
70563
70687
  const code = typeof error === "object" && error !== null && "code" in error ? String(error.code) : "unreadable";
@@ -70751,7 +70875,7 @@ var exports_cli_runtime = {};
70751
70875
  __export(exports_cli_runtime, {
70752
70876
  createCliRuntime: () => createCliRuntime
70753
70877
  });
70754
- import path73 from "node:path";
70878
+ import path74 from "node:path";
70755
70879
  function attachmentFailureMessage(attachment) {
70756
70880
  const isNonGitContext = attachment.code === "NOT_A_GIT_REPO" || attachment.code === "GIT_NOT_AVAILABLE";
70757
70881
  return isNonGitContext ? "Kibi requires an active Git branch outside a repository; set KIBI_BRANCH explicitly for a standalone workspace." : `Failed to resolve active branch: ${attachment.error}`;
@@ -70766,7 +70890,7 @@ function createDefaultProlog(root, branch) {
70766
70890
  }
70767
70891
  function workspaceRoot(options2) {
70768
70892
  const envRoot = process.env.KIBI_WORKSPACE ?? process.env.KIBI_PROJECT_ROOT ?? process.env.KIBI_ROOT;
70769
- return path73.resolve(options2.workspaceRoot ?? envRoot ?? process.cwd());
70893
+ return path74.resolve(options2.workspaceRoot ?? envRoot ?? process.cwd());
70770
70894
  }
70771
70895
  function quoteProlog2(value) {
70772
70896
  return value.replaceAll("'", "''");
@@ -71698,8 +71822,8 @@ var init_repair_plan = __esm(() => {
71698
71822
  });
71699
71823
 
71700
71824
  // ../cli/dist/public/operations/symbol-repair-plan.js
71701
- import { existsSync as existsSync39, readFileSync as readFileSync43 } from "node:fs";
71702
- import path74 from "node:path";
71825
+ import { existsSync as existsSync39, readFileSync as readFileSync44 } from "node:fs";
71826
+ import path75 from "node:path";
71703
71827
  function sourceFileOf(entity) {
71704
71828
  const value = entity.sourceFile ?? entity.source;
71705
71829
  return typeof value === "string" && value.trim() ? value.trim() : null;
@@ -71730,7 +71854,7 @@ async function inspectCoordinateRepairs(symbols, workspaceRoot) {
71730
71854
  let source = null;
71731
71855
  if (sourceFile) {
71732
71856
  try {
71733
- source = readFileSync43(path74.resolve(workspaceRoot, sourceFile), "utf8");
71857
+ source = readFileSync44(path75.resolve(workspaceRoot, sourceFile), "utf8");
71734
71858
  } catch {}
71735
71859
  }
71736
71860
  const extracted = entry.title.length > 0 && coordinatesPresent(enriched[index] ?? {});
@@ -71819,11 +71943,11 @@ async function buildSymbolRepairPlan(rows, context) {
71819
71943
  const source = sourceFileOf(symbol);
71820
71944
  if (!source || extractedByPath.has(source))
71821
71945
  continue;
71822
- const absolute = path74.isAbsolute(source) ? source : path74.resolve(context.workspaceRoot, source);
71946
+ const absolute = path75.isAbsolute(source) ? source : path75.resolve(context.workspaceRoot, source);
71823
71947
  if (!existsSync39(absolute))
71824
71948
  continue;
71825
71949
  try {
71826
- const content = readFileSync43(absolute, "utf8");
71950
+ const content = readFileSync44(absolute, "utf8");
71827
71951
  const analysis = analyzeSourceText(absolute, content);
71828
71952
  if (analysis.providerId === null)
71829
71953
  continue;
@@ -71841,7 +71965,7 @@ async function buildSymbolRepairPlan(rows, context) {
71841
71965
  if (!entity)
71842
71966
  return [];
71843
71967
  const source = sourceFileOf(entity);
71844
- const absolute = source ? path74.isAbsolute(source) ? source : path74.resolve(context.workspaceRoot, source) : null;
71968
+ const absolute = source ? path75.isAbsolute(source) ? source : path75.resolve(context.workspaceRoot, source) : null;
71845
71969
  const exists = absolute !== null && existsSync39(absolute);
71846
71970
  const candidates = currentCandidates(entity, symbols, extractedByPath);
71847
71971
  const extraction = source ? extractedByPath.get(source) : undefined;
@@ -72383,7 +72507,7 @@ __export(exports_schema6, {
72383
72507
  buildSchema6MigrationFragment: () => buildSchema6MigrationFragment,
72384
72508
  migrationSyncAction: () => migrationSyncAction
72385
72509
  });
72386
- import path75 from "node:path";
72510
+ import path76 from "node:path";
72387
72511
  function rederiveAction(plan) {
72388
72512
  const changed = plan.changes.filter((change) => change.change !== "kept");
72389
72513
  return migrationAction({
@@ -72450,7 +72574,7 @@ function unapprovedExceptionsFromSources(workspaceRoot) {
72450
72574
  } catch {}
72451
72575
  }
72452
72576
  try {
72453
- relationships.push(...readAllShards(path75.join(workspaceRoot, ".kb")));
72577
+ relationships.push(...readAllShards(path76.join(workspaceRoot, ".kb")));
72454
72578
  } catch {}
72455
72579
  const superseded = new Set(relationships.filter((relationship) => relationship.type === "supersedes").map((relationship) => relationship.to));
72456
72580
  const exempts = new Map;
@@ -73854,8 +73978,8 @@ var init_cli_json_command = __esm(() => {
73854
73978
  });
73855
73979
 
73856
73980
  // ../cli/dist/commands/migrate.js
73857
- import { existsSync as existsSync40, mkdirSync as mkdirSync16, readFileSync as readFileSync44, renameSync as renameSync13, writeFileSync as writeFileSync19 } from "node:fs";
73858
- import * as path76 from "node:path";
73981
+ import { existsSync as existsSync40, mkdirSync as mkdirSync16, readFileSync as readFileSync45, renameSync as renameSync13, writeFileSync as writeFileSync19 } from "node:fs";
73982
+ import * as path77 from "node:path";
73859
73983
  function migrationStepsFor(fromVersion) {
73860
73984
  const start = Math.max(0, fromVersion ?? 0);
73861
73985
  return SCHEMA_MIGRATION_STEPS.filter((step) => step.from >= start);
@@ -73864,8 +73988,8 @@ function printWarning(message) {
73864
73988
  console.log(`Warning: ${message}`);
73865
73989
  }
73866
73990
  function toRelativePath(cwd, filePath) {
73867
- const relativePath = path76.relative(cwd, filePath);
73868
- return relativePath.length > 0 ? relativePath : path76.basename(filePath);
73991
+ const relativePath = path77.relative(cwd, filePath);
73992
+ return relativePath.length > 0 ? relativePath : path77.basename(filePath);
73869
73993
  }
73870
73994
  function resolveMigrationBranch(cwd) {
73871
73995
  const result = resolveBranchAttachment(cwd);
@@ -73892,7 +74016,7 @@ function writeJsonAtomically(filePath, value) {
73892
74016
  `);
73893
74017
  }
73894
74018
  function writeTextAtomically(filePath, content) {
73895
- mkdirSync16(path76.dirname(filePath), { recursive: true });
74019
+ mkdirSync16(path77.dirname(filePath), { recursive: true });
73896
74020
  const tempPath = `${filePath}.tmp-${process.pid}-${Date.now()}`;
73897
74021
  writeFileSync19(tempPath, content, "utf8");
73898
74022
  renameSync13(tempPath, filePath);
@@ -73944,7 +74068,7 @@ function hasTraceabilityRelationship2(symbol) {
73944
74068
  });
73945
74069
  }
73946
74070
  function getGranularNames(cwd, sourceFile) {
73947
- const absolutePath = path76.isAbsolute(sourceFile) ? sourceFile : path76.join(cwd, sourceFile);
74071
+ const absolutePath = path77.isAbsolute(sourceFile) ? sourceFile : path77.join(cwd, sourceFile);
73948
74072
  if (!existsSync40(absolutePath)) {
73949
74073
  return new Set;
73950
74074
  }
@@ -73952,7 +74076,7 @@ function getGranularNames(cwd, sourceFile) {
73952
74076
  path: sourceFile,
73953
74077
  status: "M",
73954
74078
  hunkRanges: [{ start: 1, end: Number.MAX_SAFE_INTEGER }],
73955
- content: readFileSync44(absolutePath, "utf8")
74079
+ content: readFileSync45(absolutePath, "utf8")
73956
74080
  });
73957
74081
  return new Set(symbols.map((symbol) => symbol.name));
73958
74082
  }
@@ -73994,11 +74118,11 @@ function addLegacyReasonsToManifestText(content, symbolIds) {
73994
74118
  `);
73995
74119
  }
73996
74120
  function migrateSymbolGranularity(options2) {
73997
- const manifestPath = options2.manifestPath ?? path76.join(options2.cwd, CANONICAL_ENTITY_PATHS.symbols);
74121
+ const manifestPath = options2.manifestPath ?? path77.join(options2.cwd, CANONICAL_ENTITY_PATHS.symbols);
73998
74122
  if (!existsSync40(manifestPath)) {
73999
74123
  return { count: 0, manifestPath };
74000
74124
  }
74001
- const manifestContent = readFileSync44(manifestPath, "utf8");
74125
+ const manifestContent = readFileSync45(manifestPath, "utf8");
74002
74126
  const parsed = load(manifestContent);
74003
74127
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
74004
74128
  return { count: 0, manifestPath };
@@ -74138,7 +74262,7 @@ async function migrateCommand(options2 = {}) {
74138
74262
  if (options2.applySafe === true || options2.format === "json" || options2.yes !== true && options2.dryRun !== true) {
74139
74263
  return migratePlanCommand(options2);
74140
74264
  }
74141
- const cwd = path76.resolve(options2.workspaceRoot ?? process.cwd());
74265
+ const cwd = path77.resolve(options2.workspaceRoot ?? process.cwd());
74142
74266
  const branchResult = resolveMigrationBranch(cwd);
74143
74267
  if ("error" in branchResult) {
74144
74268
  console.error(branchResult.error);
@@ -74166,7 +74290,7 @@ async function migrateCommand(options2 = {}) {
74166
74290
  ...branchWarnings,
74167
74291
  ...migrationWarning ? [migrationWarning] : []
74168
74292
  ];
74169
- const auditPath = path76.join(cwd, ".kb", "migrations", `${branch}.json`);
74293
+ const auditPath = path77.join(cwd, ".kb", "migrations", `${branch}.json`);
74170
74294
  for (const warning of warnings) {
74171
74295
  printWarning(warning);
74172
74296
  }
@@ -74240,7 +74364,7 @@ async function migrateCommand(options2 = {}) {
74240
74364
  const preview = migrateSymbolGranularity({
74241
74365
  cwd,
74242
74366
  dryRun: true,
74243
- manifestPath: path76.join(cwd, symbolsSource)
74367
+ manifestPath: path77.join(cwd, symbolsSource)
74244
74368
  });
74245
74369
  if (preview.count > 0) {
74246
74370
  console.log(`dry run: would mark ${preview.count} legacy coarse symbol link(s) as legacy-link.`);
@@ -74422,7 +74546,7 @@ async function buildWorkspaceMigrationPlan(workspaceRoot = process.cwd()) {
74422
74546
  return mergeMigrationPlans(plans);
74423
74547
  }
74424
74548
  async function migratePlanCommand(options2) {
74425
- const workspaceRoot = path76.resolve(options2.workspaceRoot ?? process.cwd());
74549
+ const workspaceRoot = path77.resolve(options2.workspaceRoot ?? process.cwd());
74426
74550
  const plan = await buildWorkspaceMigrationPlan(workspaceRoot);
74427
74551
  if (options2.applySafe === true) {
74428
74552
  if (!options2.approvedPlanHash) {
@@ -74545,7 +74669,7 @@ var init_migrate = __esm(() => {
74545
74669
 
74546
74670
  // ../cli/dist/operations/planning/compile-intent.js
74547
74671
  import { createHash as createHash39 } from "node:crypto";
74548
- import path77 from "node:path";
74672
+ import path78 from "node:path";
74549
74673
  function compilePlanHash(plan) {
74550
74674
  const { planHash: _ignored, ...body } = plan;
74551
74675
  return hash2(body);
@@ -74582,7 +74706,7 @@ function requiredIntent(args) {
74582
74706
  return intent;
74583
74707
  }
74584
74708
  function validateLocation(location) {
74585
- if (!text7(location.path) || path77.isAbsolute(location.path) || location.path.split(/[\\/]/).includes("..")) {
74709
+ if (!text7(location.path) || path78.isAbsolute(location.path) || location.path.split(/[\\/]/).includes("..")) {
74586
74710
  throw new Error("Compile intent failed: sourceLocations.path must be workspace-relative");
74587
74711
  }
74588
74712
  }
@@ -74700,7 +74824,7 @@ async function sourceHashes(context, locations) {
74700
74824
  const hashes = {};
74701
74825
  for (const relative of sourceFilesFor(locations)) {
74702
74826
  try {
74703
- const contents = context.fs ? await context.fs.readFile(path77.join(context.workspaceRoot, relative)) : null;
74827
+ const contents = context.fs ? await context.fs.readFile(path78.join(context.workspaceRoot, relative)) : null;
74704
74828
  hashes[relative] = contents === null ? null : createHash39("sha256").update(contents).digest("hex");
74705
74829
  } catch {
74706
74830
  hashes[relative] = null;
@@ -74757,7 +74881,7 @@ async function existingRequirementBody(context, source) {
74757
74881
  if (!context.fs || !source.endsWith(".md"))
74758
74882
  return;
74759
74883
  try {
74760
- const raw = await context.fs.readFile(path77.join(context.workspaceRoot, source));
74884
+ const raw = await context.fs.readFile(path78.join(context.workspaceRoot, source));
74761
74885
  return readAuthoredEntity(String(raw), source)?.body ?? undefined;
74762
74886
  } catch {
74763
74887
  return;
@@ -75287,7 +75411,7 @@ var init_compile_intent = __esm(() => {
75287
75411
 
75288
75412
  // ../cli/dist/operations/planning/apply-plan.js
75289
75413
  import { createHash as createHash40, randomUUID as randomUUID6 } from "node:crypto";
75290
- import path78 from "node:path";
75414
+ import path79 from "node:path";
75291
75415
  function text8(value) {
75292
75416
  return typeof value === "string" ? value.trim() : "";
75293
75417
  }
@@ -75352,7 +75476,7 @@ function isBootstrapApplyArgs(args) {
75352
75476
  return "plan" in args && args.plan.version === "kibi.bootstrap-plan.v1";
75353
75477
  }
75354
75478
  function assertSourceWriteStaysInWorkspace(root, absolute, writePath) {
75355
- if (absolute !== root && !absolute.startsWith(`${root}${path78.sep}`)) {
75479
+ if (absolute !== root && !absolute.startsWith(`${root}${path79.sep}`)) {
75356
75480
  throw new Error(`Apply plan failed: sourceWrites.path escapes workspace: ${writePath}`);
75357
75481
  }
75358
75482
  }
@@ -75532,13 +75656,13 @@ function topologicalActions(actions) {
75532
75656
  async function validateSources(context, sourceHashes) {
75533
75657
  let checked = 0;
75534
75658
  for (const [relative, expected] of Object.entries(sourceHashes)) {
75535
- if (!relative || path78.isAbsolute(relative) || relative.split(/[\\/]/).includes(".."))
75659
+ if (!relative || path79.isAbsolute(relative) || relative.split(/[\\/]/).includes(".."))
75536
75660
  throw new Error("Apply plan failed: source hash paths must be workspace-relative");
75537
75661
  if (!context.fs)
75538
75662
  throw new Error("Apply plan failed: source hashes require a filesystem-capable runtime");
75539
75663
  let actual;
75540
75664
  try {
75541
- actual = digest4(await context.fs.readFile(path78.join(context.workspaceRoot, relative)));
75665
+ actual = digest4(await context.fs.readFile(path79.join(context.workspaceRoot, relative)));
75542
75666
  } catch {
75543
75667
  actual = null;
75544
75668
  }
@@ -75549,19 +75673,19 @@ async function validateSources(context, sourceHashes) {
75549
75673
  return checked;
75550
75674
  }
75551
75675
  async function resolveSourceWriteTarget(workspaceRoot, fsPort, write) {
75552
- if (!write.path || path78.isAbsolute(write.path) || write.path.split(/[\\/]/).includes("..")) {
75676
+ if (!write.path || path79.isAbsolute(write.path) || write.path.split(/[\\/]/).includes("..")) {
75553
75677
  throw new Error(`Apply plan failed: sourceWrites.path must be workspace-relative: ${write.path}`);
75554
75678
  }
75555
- const absolute = path78.resolve(workspaceRoot, write.path);
75556
- const root = path78.resolve(workspaceRoot);
75679
+ const absolute = path79.resolve(workspaceRoot, write.path);
75680
+ const root = path79.resolve(workspaceRoot);
75557
75681
  assertSourceWriteStaysInWorkspace(root, absolute, write.path);
75558
- const relative = path78.relative(root, absolute).split(path78.sep).join("/");
75682
+ const relative = path79.relative(root, absolute).split(path79.sep).join("/");
75559
75683
  if (relative === ".kb" || isDerivedKbPath(relative)) {
75560
75684
  throw new Error("Apply plan failed: sourceWrites.path cannot target Kibi's derived .kb runtime trees");
75561
75685
  }
75562
75686
  const realRoot = canonicalFilesystemPath(root);
75563
75687
  const realExisting = canonicalFilesystemPath(absolute);
75564
- if (realExisting !== realRoot && !realExisting.startsWith(`${realRoot}${path78.sep}`)) {
75688
+ if (realExisting !== realRoot && !realExisting.startsWith(`${realRoot}${path79.sep}`)) {
75565
75689
  throw new Error(`Apply plan failed: sourceWrites.path follows a symlink outside the workspace: ${write.path}`);
75566
75690
  }
75567
75691
  const existing = await fsPort.readFile(absolute).catch(() => {
@@ -75592,7 +75716,7 @@ async function applySourceWrites(context, writes, planHash, allowReplay = false,
75592
75716
  throw new Error("Apply plan failed: sourceWrites require a filesystem-capable runtime");
75593
75717
  }
75594
75718
  const fsPort = context.fs;
75595
- const journalPath = path78.join(context.workspaceRoot, ".kb", "recovery", `source-writes-${planHash.slice(0, 16)}.json`);
75719
+ const journalPath = path79.join(context.workspaceRoot, ".kb", "recovery", `source-writes-${planHash.slice(0, 16)}.json`);
75596
75720
  const journalId = `source-writes-${planHash.slice(0, 16)}`;
75597
75721
  const sameEntries = (entries) => entries.length === writes.length && entries.every((entry) => writes.some((write) => write.path === entry.path && (write.mode ?? "write") === entry.mode && write.beforeHash === entry.beforeHash && write.afterHash === entry.afterHash));
75598
75722
  const readJournal = async () => {
@@ -75615,7 +75739,7 @@ async function applySourceWrites(context, writes, planHash, allowReplay = false,
75615
75739
  let allAfter = true;
75616
75740
  for (const entry of prior.entries) {
75617
75741
  try {
75618
- const current = await context.fs.readFile(path78.resolve(context.workspaceRoot, entry.path));
75742
+ const current = await context.fs.readFile(path79.resolve(context.workspaceRoot, entry.path));
75619
75743
  if (entry.afterHash === null || digest4(current) !== entry.afterHash) {
75620
75744
  allAfter = false;
75621
75745
  }
@@ -75637,7 +75761,7 @@ async function applySourceWrites(context, writes, planHash, allowReplay = false,
75637
75761
  }
75638
75762
  if (prior && (prior.state === "prepared" || prior.state === "publishing_sources")) {
75639
75763
  for (const entry of prior.entries) {
75640
- const absolute = path78.resolve(context.workspaceRoot, entry.path);
75764
+ const absolute = path79.resolve(context.workspaceRoot, entry.path);
75641
75765
  let current;
75642
75766
  try {
75643
75767
  current = await context.fs.readFile(absolute);
@@ -75670,7 +75794,7 @@ async function applySourceWrites(context, writes, planHash, allowReplay = false,
75670
75794
  const { absolute, existing, mode } = await resolveSourceWriteTarget(context.workspaceRoot, fsPort, write);
75671
75795
  originals.push({ absolute, body: existing });
75672
75796
  paths.push(write.path);
75673
- const stageBase = path78.join(context.workspaceRoot, ".kb", "recovery", `${journalId}-${entries.length}`);
75797
+ const stageBase = path79.join(context.workspaceRoot, ".kb", "recovery", `${journalId}-${entries.length}`);
75674
75798
  entries.push({
75675
75799
  path: write.path,
75676
75800
  mode,
@@ -75681,7 +75805,7 @@ async function applySourceWrites(context, writes, planHash, allowReplay = false,
75681
75805
  afterStage: `${stageBase}.after`
75682
75806
  });
75683
75807
  }
75684
- await context.fs.mkdir(path78.dirname(journalPath));
75808
+ await context.fs.mkdir(path79.dirname(journalPath));
75685
75809
  for (let index = 0;index < writes.length; index += 1) {
75686
75810
  const original = originals[index];
75687
75811
  const entry = entries[index];
@@ -75702,7 +75826,7 @@ async function applySourceWrites(context, writes, planHash, allowReplay = false,
75702
75826
  const write = writes[index];
75703
75827
  if (!absolute || !write)
75704
75828
  continue;
75705
- await context.fs.mkdir(path78.dirname(absolute));
75829
+ await context.fs.mkdir(path79.dirname(absolute));
75706
75830
  await context.fs.writeFile(journalPath, `${JSON.stringify({ version: 1, planHash, state: "publishing_sources", entries }, null, 2)}
75707
75831
  `);
75708
75832
  if ((write.mode ?? "write") === "delete") {
@@ -75754,7 +75878,7 @@ async function applySourceWrites(context, writes, planHash, allowReplay = false,
75754
75878
  } catch {}
75755
75879
  }
75756
75880
  try {
75757
- await context.fs.mkdir(path78.dirname(journalPath));
75881
+ await context.fs.mkdir(path79.dirname(journalPath));
75758
75882
  await context.fs.writeFile(journalPath, `${JSON.stringify({ version: 1, planHash, state: "rolled_back", entries }, null, 2)}
75759
75883
  `);
75760
75884
  } catch {}
@@ -75771,7 +75895,7 @@ async function applySourceWrites(context, writes, planHash, allowReplay = false,
75771
75895
  async function markSourceJournal(context, journalId, state) {
75772
75896
  if (!journalId || !context.fs)
75773
75897
  return;
75774
- const journalPath = path78.join(context.workspaceRoot, ".kb", "recovery", `${journalId}.json`);
75898
+ const journalPath = path79.join(context.workspaceRoot, ".kb", "recovery", `${journalId}.json`);
75775
75899
  try {
75776
75900
  const current = JSON.parse(await context.fs.readFile(journalPath));
75777
75901
  await context.fs.writeFile(journalPath, `${JSON.stringify({ ...current, state }, null, 2)}
@@ -75786,7 +75910,7 @@ async function executeSourceRecovery(args, context, onCommitted = () => {
75786
75910
  if (!/^[A-Za-z0-9._-]+$/.test(args.recoveryJournalId)) {
75787
75911
  throw new Error("Source recovery journal ID is invalid");
75788
75912
  }
75789
- const journalPath = path78.join(context.workspaceRoot, ".kb", "recovery", `${args.recoveryJournalId}.json`);
75913
+ const journalPath = path79.join(context.workspaceRoot, ".kb", "recovery", `${args.recoveryJournalId}.json`);
75790
75914
  const journal = JSON.parse(await context.fs.readFile(journalPath));
75791
75915
  if (journal.version !== 1 || typeof journal.planHash !== "string" || !Array.isArray(journal.entries) || !["sources_committed", "compiled_published", "repair_required"].includes(journal.state ?? "")) {
75792
75916
  throw new Error("Source recovery requires a committed or repair_required journal");
@@ -75902,7 +76026,7 @@ async function executeBootstrapPlan(args, context, recovery = false, remainingAc
75902
76026
  if (!status)
75903
76027
  throw new Error("Bootstrap apply failed: status returned no payload");
75904
76028
  const journalId = `bootstrap-${args.plan.planHash.slice(0, 16)}`;
75905
- const journalPath = path78.join(context.workspaceRoot, ".kb", "recovery", `${journalId}.json`);
76029
+ const journalPath = path79.join(context.workspaceRoot, ".kb", "recovery", `${journalId}.json`);
75906
76030
  if (!recovery && context.fs) {
75907
76031
  try {
75908
76032
  await context.fs.readFile(journalPath);
@@ -75935,7 +76059,7 @@ async function executeBootstrapPlan(args, context, recovery = false, remainingAc
75935
76059
  const writeJournal = async (state, activeActionId, currentCheckpoint = lastCheckpoint) => {
75936
76060
  if (!context.fs)
75937
76061
  return;
75938
- await context.fs.mkdir(path78.dirname(journalPath));
76062
+ await context.fs.mkdir(path79.dirname(journalPath));
75939
76063
  await context.fs.writeFile(journalPath, `${JSON.stringify({
75940
76064
  version: 2,
75941
76065
  kind: "bootstrap",
@@ -76205,7 +76329,7 @@ async function dispatchApplyPlan(args, context, onCommitted, recovered) {
76205
76329
  throw new Error("Bootstrap recovery requires a filesystem-capable runtime");
76206
76330
  if (!/^bootstrap-[a-f0-9]{16}$/.test(args.recoveryJournalId))
76207
76331
  throw new Error("Bootstrap recovery journal ID is invalid");
76208
- const journalPath = path78.join(context.workspaceRoot, ".kb", "recovery", `${args.recoveryJournalId}.json`);
76332
+ const journalPath = path79.join(context.workspaceRoot, ".kb", "recovery", `${args.recoveryJournalId}.json`);
76209
76333
  const journal = JSON.parse(await context.fs.readFile(journalPath));
76210
76334
  if (journal.version !== 2 || journal.kind !== "bootstrap" || !journal.plan)
76211
76335
  throw new Error("Bootstrap recovery journal is invalid");
@@ -76389,7 +76513,7 @@ async function planFileWrites(context, prolog, fsPort, sourceWrites, steps, now)
76389
76513
  const relative = canonicalSourcePath(context, step.input, step.entity, existing);
76390
76514
  let file = files.get(relative);
76391
76515
  if (file === undefined) {
76392
- const existingBytes = await fsPort.readFile(path78.join(workspaceRoot, relative)).catch(() => {
76516
+ const existingBytes = await fsPort.readFile(path79.join(workspaceRoot, relative)).catch(() => {
76393
76517
  return;
76394
76518
  });
76395
76519
  const before = existingBytes ?? null;
@@ -76414,8 +76538,8 @@ async function planFileWrites(context, prolog, fsPort, sourceWrites, steps, now)
76414
76538
  file.after = after;
76415
76539
  file.afterHash = contentHash(after);
76416
76540
  }
76417
- const root = path78.resolve(workspaceRoot);
76418
- const kbRoot = path78.join(workspaceRoot, ".kb");
76541
+ const root = path79.resolve(workspaceRoot);
76542
+ const kbRoot = path79.join(workspaceRoot, ".kb");
76419
76543
  const createdAt = now.toISOString();
76420
76544
  for (const step of steps) {
76421
76545
  for (const relationship of step.relationships) {
@@ -76426,7 +76550,7 @@ async function planFileWrites(context, prolog, fsPort, sourceWrites, steps, now)
76426
76550
  continue;
76427
76551
  const shardPath = computeShardPath(kbRoot, from);
76428
76552
  assertRelationshipShardContained(workspaceRoot, shardPath);
76429
- const relative = path78.relative(root, path78.resolve(shardPath)).split(path78.sep).join("/");
76553
+ const relative = path79.relative(root, path79.resolve(shardPath)).split(path79.sep).join("/");
76430
76554
  let file = files.get(relative);
76431
76555
  if (file === undefined) {
76432
76556
  const existing = await fsPort.readFile(shardPath).catch(() => null);
@@ -76911,7 +77035,7 @@ async function applyingBootstrapJournal(args, context) {
76911
77035
  return;
76912
77036
  if (!/^bootstrap-[a-f0-9]{16}$/.test(args.recoveryJournalId))
76913
77037
  return;
76914
- const journalPath = path78.join(context.workspaceRoot, ".kb", "recovery", `${args.recoveryJournalId}.json`);
77038
+ const journalPath = path79.join(context.workspaceRoot, ".kb", "recovery", `${args.recoveryJournalId}.json`);
76915
77039
  try {
76916
77040
  const journal = JSON.parse(await context.fs.readFile(journalPath));
76917
77041
  return journal.kind === "bootstrap" && journal.state === "applying" ? journalPath : undefined;
@@ -77631,10 +77755,10 @@ function evaluateContractAgainstRun(artifact, contract) {
77631
77755
  var MAX_ATTRIBUTED_MEMBERS = 5;
77632
77756
 
77633
77757
  // ../cli/dist/proof/integrations.js
77634
- import { existsSync as existsSync41, readFileSync as readFileSync45 } from "node:fs";
77635
- import path79 from "node:path";
77758
+ import { existsSync as existsSync41, readFileSync as readFileSync46 } from "node:fs";
77759
+ import path80 from "node:path";
77636
77760
  function integrationsPath(workspaceRoot) {
77637
- return path79.join(workspaceRoot, PROOF_INTEGRATIONS_PATH);
77761
+ return path80.join(workspaceRoot, PROOF_INTEGRATIONS_PATH);
77638
77762
  }
77639
77763
  function proofIntegrationErrors(value) {
77640
77764
  const file = record5(value);
@@ -77691,7 +77815,7 @@ function loadProofIntegrations(workspaceRoot) {
77691
77815
  }
77692
77816
  let parsed;
77693
77817
  try {
77694
- parsed = JSON.parse(readFileSync45(filePath, "utf8"));
77818
+ parsed = JSON.parse(readFileSync46(filePath, "utf8"));
77695
77819
  } catch (error) {
77696
77820
  return {
77697
77821
  available: false,
@@ -78539,9 +78663,9 @@ init_ir();
78539
78663
  import { createHash as createHash41 } from "node:crypto";
78540
78664
 
78541
78665
  // src/skill-system/loader.ts
78542
- import { existsSync as existsSync44, readFileSync as readFileSync47, readdirSync as readdirSync13, realpathSync as realpathSync10 } from "node:fs";
78666
+ import { existsSync as existsSync44, readFileSync as readFileSync48, readdirSync as readdirSync13, realpathSync as realpathSync10 } from "node:fs";
78543
78667
  import { dirname as dirname21, join as join32, resolve as resolve29 } from "node:path";
78544
- import { fileURLToPath as fileURLToPath4 } from "node:url";
78668
+ import { fileURLToPath as fileURLToPath5 } from "node:url";
78545
78669
 
78546
78670
  // src/skill-system/errors.ts
78547
78671
  class SkillNotFoundError2 extends Error {
@@ -78724,7 +78848,7 @@ function isStringArray2(value) {
78724
78848
  }
78725
78849
 
78726
78850
  // src/skill-system/loader.ts
78727
- var moduleDir = dirname21(fileURLToPath4(import.meta.url));
78851
+ var moduleDir = dirname21(fileURLToPath5(import.meta.url));
78728
78852
  var overrideSkillsDir;
78729
78853
  function defaultBundledSkillsDir2() {
78730
78854
  return existsSync44(resolve29(moduleDir, "skills")) ? resolve29(moduleDir, "skills") : resolve29(moduleDir, "../skills");
@@ -78785,7 +78909,7 @@ function readBundle2(bundle, id, resourcePath) {
78785
78909
  throw new SkillResourceNotFoundError2(id, resourcePath);
78786
78910
  }
78787
78911
  assertMaxBytes2(candidate, RESOURCE_MAX_BYTES2);
78788
- return readFileSync47(candidate, "utf8");
78912
+ return readFileSync48(candidate, "utf8");
78789
78913
  }
78790
78914
  // src/skill-operations.ts
78791
78915
  function assertNonEmptyString2(value, field) {
@@ -78942,7 +79066,7 @@ init_symbols_coordinator2();
78942
79066
  // ../cli/dist/env/bootstrap.js
78943
79067
  import fs11 from "node:fs";
78944
79068
  import os2 from "node:os";
78945
- import path80 from "node:path";
79069
+ import path81 from "node:path";
78946
79070
  var WORKSPACE_ENV_KEYS = [
78947
79071
  "KIBI_WORKSPACE",
78948
79072
  "KIBI_PROJECT_ROOT",
@@ -78968,13 +79092,13 @@ function readFirstEnv(env, keys) {
78968
79092
  return null;
78969
79093
  }
78970
79094
  function nextAncestorDirectory2(current) {
78971
- const parent = path80.dirname(current);
79095
+ const parent = path81.dirname(current);
78972
79096
  return parent === current ? undefined : parent;
78973
79097
  }
78974
79098
  function findUpwards(startDir, marker) {
78975
- let current = path80.resolve(startDir);
79099
+ let current = path81.resolve(startDir);
78976
79100
  while (current !== undefined) {
78977
- if (fs11.existsSync(path80.join(current, marker))) {
79101
+ if (fs11.existsSync(path81.join(current, marker))) {
78978
79102
  return current;
78979
79103
  }
78980
79104
  current = nextAncestorDirectory2(current);
@@ -78984,24 +79108,24 @@ function findUpwards(startDir, marker) {
78984
79108
  function resolveKibiWorkspaceRoot(startDir = process.cwd(), env = process.env) {
78985
79109
  const envRoot = readFirstEnv(env, WORKSPACE_ENV_KEYS);
78986
79110
  if (envRoot)
78987
- return path80.resolve(envRoot);
79111
+ return path81.resolve(envRoot);
78988
79112
  const kbRoot = findUpwards(startDir, ".kb");
78989
79113
  if (kbRoot)
78990
79114
  return kbRoot;
78991
79115
  const gitRoot = findUpwards(startDir, ".git");
78992
79116
  if (gitRoot)
78993
79117
  return gitRoot;
78994
- return path80.resolve(startDir);
79118
+ return path81.resolve(startDir);
78995
79119
  }
78996
79120
  function resolveEnvFilePath(envFileName, workspaceRoot) {
78997
- if (path80.isAbsolute(envFileName))
79121
+ if (path81.isAbsolute(envFileName))
78998
79122
  return envFileName;
78999
- return path80.resolve(workspaceRoot, envFileName);
79123
+ return path81.resolve(workspaceRoot, envFileName);
79000
79124
  }
79001
79125
  function resolveKibiUserEnvPath(options2 = {}) {
79002
79126
  const env = options2.env ?? process.env;
79003
- const xdg = options2.xdgConfigHome?.trim() || env.XDG_CONFIG_HOME?.trim() || path80.join(options2.homedir ?? os2.homedir(), ".config");
79004
- return path80.join(xdg, "kibi", "env");
79127
+ const xdg = options2.xdgConfigHome?.trim() || env.XDG_CONFIG_HOME?.trim() || path81.join(options2.homedir ?? os2.homedir(), ".config");
79128
+ return path81.join(xdg, "kibi", "env");
79005
79129
  }
79006
79130
  function resolveKibiProjectEnvPath(workspaceRoot, env = process.env) {
79007
79131
  const override = env.KIBI_ENV_FILE?.trim();