kibi-cli 2.26.2 → 2.26.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -41,7 +41,28 @@ export type SourceExtractionFailure = {
41
41
  * new authoring.
42
42
  */
43
43
  baseline?: boolean;
44
+ /**
45
+ * The semantic source hash and contract flag of the source's last
46
+ * successful compilation, carried while it fails.
47
+ */
48
+ semanticHash?: string;
49
+ semanticContract?: boolean;
44
50
  };
51
+ /**
52
+ * Whether a requirement source the last sync could not extract is still
53
+ * accepted without a complete proposition inventory once it compiles with
54
+ * prose hashing to `sourceHash`. Legacy content that missed the store's first
55
+ * compilation keeps the baseline; a source that compiled before keeps it only
56
+ * while its prose is the prose it last compiled with. kibi sync and kb_upsert
57
+ * on the uncompiled file both apply this rule, so a write one accepts the
58
+ * other never refuses.
59
+ */
60
+ export declare function failedSourceKeepsSemanticBaseline(failure: SourceExtractionFailure, sourceHash: string): boolean;
61
+ /**
62
+ * What the last sync recorded about an authored source it could not extract,
63
+ * the record the next sync judges the source by; undefined when it compiled.
64
+ */
65
+ export declare function sourceExtractionFailure(workspaceRoot: string, storePath: string, file: string, deps?: Partial<SyncCacheDeps>): SourceExtractionFailure | undefined;
45
66
  /**
46
67
  * v2: cache identities are workspace-root relative instead of process-cwd
47
68
  * relative, and symbol manifests are fingerprinted together with their
@@ -1 +1 @@
1
- {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/cache.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAO7E,UAAU,aAAa;IACrB,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,aAAa,EAAE,OAAO,aAAa,CAAC;CACrC;AAaD,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,sEAAsE;IACtE,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,iEAAiE;IACjE,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3C,kEAAkE;IAClE,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,yEAAyE;IACzE,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;CAC9D,CAAC;AAEF,2DAA2D;AAE3D,MAAM,MAAM,uBAAuB,GAAG;IACpC,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,IAAI,CAAC;AACpC,eAAO,MAAM,iBAAiB,QAA2B,CAAC;AAE1D;;;;;;GAMG;AAEH,eAAO,MAAM,yBAAyB,QAEtB,CAAC;AAEjB;;;;GAIG;AAEH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAC5B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAyBhC;AAED,gFAAgF;AAEhF,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AAEnE;;;;;;GAMG;AAEH,wBAAgB,8BAA8B,CAC5C,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAC5B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CA4C3B;AAED,uEAAuE;AAEvE,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,MAAM,CAIR;AAED,wBAAgB,UAAU,CAAC,aAAa,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAM1E;AAED,wBAAgB,QAAQ,CAEtB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAC5B,MAAM,CAIR;AAED,iEAAiE;AACjE,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAerD;AAED;;;;;GAKG;AAEH,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,GAAG,IAAI,EAC9B,IAAI,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAC5B,MAAM,CA4FR;AAED,wBAAgB,aAAa,CAE3B,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,EAC7B,OAAO,GAAE;IACP,oEAAoE;IACpE,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAClC,GACL,SAAS,CAiEX;AAED,wBAAgB,cAAc,CAE5B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,SAAS,EAChB,IAAI,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAC5B,IAAI,CAaN;AAED,wBAAgB,aAAa,CAE3B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,GAC5B,IAAI,CASN"}
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/cache.ts"],"names":[],"mappings":"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"}
@@ -32,6 +32,45 @@ function resolveDeps(overrides) {
32
32
  ...overrides,
33
33
  };
34
34
  }
35
+ // implements REQ-kibi-uncompiled-source-semantic-baseline
36
+ /**
37
+ * Whether a requirement source the last sync could not extract is still
38
+ * accepted without a complete proposition inventory once it compiles with
39
+ * prose hashing to `sourceHash`. Legacy content that missed the store's first
40
+ * compilation keeps the baseline; a source that compiled before keeps it only
41
+ * while its prose is the prose it last compiled with. kibi sync and kb_upsert
42
+ * on the uncompiled file both apply this rule, so a write one accepts the
43
+ * other never refuses.
44
+ */
45
+ export function failedSourceKeepsSemanticBaseline(failure, sourceHash) {
46
+ if (failure.semanticContract === true)
47
+ return false;
48
+ return failure.semanticHash === undefined
49
+ ? failure.baseline === true
50
+ : failure.semanticHash === sourceHash;
51
+ }
52
+ function readExtractionFailures(cachePath, resolved) {
53
+ if (!resolved.existsSync(cachePath))
54
+ return {};
55
+ try {
56
+ const parsed = JSON.parse(resolved.readFileSync(cachePath, "utf8"));
57
+ if (parsed.extractionFailures === null ||
58
+ typeof parsed.extractionFailures !== "object")
59
+ return {};
60
+ return parsed.extractionFailures;
61
+ }
62
+ catch {
63
+ return {};
64
+ }
65
+ }
66
+ /**
67
+ * What the last sync recorded about an authored source it could not extract,
68
+ * the record the next sync judges the source by; undefined when it compiled.
69
+ */
70
+ // implements REQ-kibi-uncompiled-source-semantic-baseline
71
+ export function sourceExtractionFailure(workspaceRoot, storePath, file, deps) {
72
+ return readExtractionFailures(path.join(storePath, "sync-cache.json"), resolveDeps(deps))[toCacheKey(workspaceRoot, path.resolve(workspaceRoot, file))];
73
+ }
35
74
  /**
36
75
  * v2: cache identities are workspace-root relative instead of process-cwd
37
76
  * relative, and symbol manifests are fingerprinted together with their
@@ -93,21 +132,7 @@ export const SOURCE_EXTRACTION_FAILED = "source_extraction_failed";
93
132
  */
94
133
  // implements REQ-kibi-uncompiled-source-visibility
95
134
  export function sourceExtractionFailureReasons(workspaceRoot, storePath, deps) {
96
- const resolved = resolveDeps(deps);
97
- const cachePath = path.join(storePath, "sync-cache.json");
98
- if (!resolved.existsSync(cachePath))
99
- return [];
100
- let failures;
101
- try {
102
- const parsed = JSON.parse(resolved.readFileSync(cachePath, "utf8"));
103
- if (parsed.extractionFailures === null ||
104
- typeof parsed.extractionFailures !== "object")
105
- return [];
106
- failures = parsed.extractionFailures;
107
- }
108
- catch {
109
- return [];
110
- }
135
+ const failures = readExtractionFailures(path.join(storePath, "sync-cache.json"), resolveDeps(deps));
111
136
  const reasons = [];
112
137
  for (const [key, failure] of Object.entries(failures).sort(([a], [b]) => a.localeCompare(b))) {
113
138
  const absolute = path.resolve(workspaceRoot, key);
@@ -1 +1 @@
1
- {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA6BjE,OAAO,EAEL,yBAAyB,EAE1B,MAAM,gDAAgD,CAAC;AAGxD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,6BAA6B,CAAC;AAyBrC,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AAkCxE,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;AAmCD,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,MAAM,EACxB,4BAA4B,UAAQ,EACpC,4BAA4B,GAAE,4BAA4B,EAAO,GAChE,MAAM,EAAE,CAuGV;AAiFD,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,yBAAyB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,UAAU,kBAAkB;IAC1B,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC3E,UAAU,CAAC,EAAE,CACX,OAAO,EAAE,yBAAyB,GAAG;QAAE,UAAU,EAAE,OAAO,CAAA;KAAE,KACzD,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,aAAa,CAAC;IAC/D,yBAAyB,CAAC,EAAE,OAAO,yBAAyB,CAAC;CAC9D;AA+FD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAGvE;AAGD,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,IAAI,GAChB,IAAI,CAMN;AAED,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,UAAU,EAAE,EACzB,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,IAAI,CAIN;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,IAAI,CAMP;AAED,wBAAgB,iCAAiC,CAC/C,WAAW,EAAE,UAAU,EAAE,EACzB,oBAAoB,EAAE,OAAO,EAC7B,iBAAiB,EAAE,MAAM,EACzB,WAAW,EAAE,MAAM,GAClB,IAAI,CAUN;AAGD,wBAAsB,WAAW,CAC/B,OAAO,GAAE;IACP,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,2EAA2E;IAC3E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,uEAAuE;IACvE,KAAK,CAAC,EAAE,OAAO,CAAC;CACZ,EACN,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,UAAU,CAAC,CAstCrB;AAED,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA6BjE,OAAO,EAEL,yBAAyB,EAE1B,MAAM,gDAAgD,CAAC;AAGxD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,6BAA6B,CAAC;AA0BrC,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AAkCxE,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;AAmCD,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,MAAM,EACxB,4BAA4B,UAAQ,EACpC,4BAA4B,GAAE,4BAA4B,EAAO,GAChE,MAAM,EAAE,CAuGV;AAiFD,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,yBAAyB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,UAAU,kBAAkB;IAC1B,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC3E,UAAU,CAAC,EAAE,CACX,OAAO,EAAE,yBAAyB,GAAG;QAAE,UAAU,EAAE,OAAO,CAAA;KAAE,KACzD,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,aAAa,CAAC;IAC/D,yBAAyB,CAAC,EAAE,OAAO,yBAAyB,CAAC;CAC9D;AA+FD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAGvE;AAGD,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,IAAI,GAChB,IAAI,CAMN;AAED,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,UAAU,EAAE,EACzB,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,IAAI,CAIN;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,IAAI,CAMP;AAED,wBAAgB,iCAAiC,CAC/C,WAAW,EAAE,UAAU,EAAE,EACzB,oBAAoB,EAAE,OAAO,EAC7B,iBAAiB,EAAE,MAAM,EACzB,WAAW,EAAE,MAAM,GAClB,IAAI,CAUN;AAGD,wBAAsB,WAAW,CAC/B,OAAO,GAAE;IACP,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,2EAA2E;IAC3E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,uEAAuE;IACvE,KAAK,CAAC,EAAE,OAAO,CAAC;CACZ,EACN,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,UAAU,CAAC,CAuuCrB;AAED,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -30,7 +30,7 @@ import { PrologProcess } from "../prolog.js";
30
30
  import { detachedHeadWriteRefusal, resolveBranchAttachment, } from "../utils/branch-resolver.js";
31
31
  import { branchStoreManifestPath, branchStorePath, ensureBranchStoreManifest, expectedBranchStoreManifest, } from "../utils/branch-store-locator.js";
32
32
  import { loadEntityPaths } from "../utils/config.js";
33
- import { SYNC_CACHE_TTL_MS, SYNC_CACHE_VERSION, SYNC_COMPILER_FINGERPRINT, hashFile, hashManifestWithCoordinates, hashNormalized, readSyncCache, toCacheKey, writeSyncCache, } from "./sync/cache.js";
33
+ import { SYNC_CACHE_TTL_MS, SYNC_CACHE_VERSION, SYNC_COMPILER_FINGERPRINT, failedSourceKeepsSemanticBaseline, hashFile, hashManifestWithCoordinates, hashNormalized, readSyncCache, toCacheKey, writeSyncCache, } from "./sync/cache.js";
34
34
  import { clearRecoveredPendingSourceReceipts, discoverSourceFiles, } from "./sync/discovery.js";
35
35
  import { normalizeExtractionSources, processExtractions, } from "./sync/extraction.js";
36
36
  import { normalizeManifestLayout, refreshManifestCoordinates, } from "./sync/manifest.js";
@@ -649,6 +649,8 @@ export async function syncCommand(options = {}, runtime = {}) {
649
649
  // kb_status can say so. A source that failed in the store's first
650
650
  // compilation (and in every sync since) is legacy content that missed the
651
651
  // semantic baseline, so it keeps the baseline treatment once it compiles.
652
+ // One that compiled before keeps the semantic hash it last compiled with,
653
+ // so restoring its prose (or fixing only what failed) is not new authoring.
652
654
  const previousExtractionFailures = syncCache.extractionFailures ?? {};
653
655
  const nextExtractionFailures = {};
654
656
  for (const failure of extraction.failures) {
@@ -656,13 +658,17 @@ export async function syncCommand(options = {}, runtime = {}) {
656
658
  const hash = nextHashes[key];
657
659
  if (hash === undefined)
658
660
  continue;
661
+ const previousFailure = previousExtractionFailures[key];
662
+ const semanticHash = syncCache.semanticHashes[key] ?? previousFailure?.semanticHash;
663
+ const semanticContract = syncCache.semanticContracts[key] ?? previousFailure?.semanticContract;
659
664
  nextExtractionFailures[key] = {
660
665
  hash,
661
666
  message: failure.message,
662
- ...(initialSemanticBaseline ||
663
- previousExtractionFailures[key]?.baseline === true
667
+ ...(initialSemanticBaseline || previousFailure?.baseline === true
664
668
  ? { baseline: true }
665
669
  : {}),
670
+ ...(semanticHash !== undefined ? { semanticHash } : {}),
671
+ ...(semanticContract !== undefined ? { semanticContract } : {}),
666
672
  };
667
673
  }
668
674
  const extractedResults = normalizeExtractionSources(extraction.results, workspaceRoot);
@@ -760,13 +766,18 @@ export async function syncCommand(options = {}, runtime = {}) {
760
766
  const advertisedContract = result.entity.semantic_inventory_version !== undefined ||
761
767
  result.entity.semantic_source_hash !== undefined ||
762
768
  result.entity.semantic_inventory !== undefined;
763
- const enforceBoundary = (!initialSemanticBaseline &&
764
- syncCache.hashes[key] === undefined &&
765
- previousExtractionFailures[key]?.baseline !== true) ||
766
- syncCache.semanticContracts[key] === true ||
767
- (previousSemanticHash !== undefined &&
768
- previousSemanticHash !== boundary.sourceHash) ||
769
- advertisedContract;
769
+ // A source the last sync could not extract is judged by what it last
770
+ // compiled with, by the rule kb_upsert applies to that file.
771
+ const previousFailure = syncCache.hashes[key] === undefined
772
+ ? previousExtractionFailures[key]
773
+ : undefined;
774
+ const enforceBoundary = advertisedContract ||
775
+ (previousFailure !== undefined
776
+ ? !failedSourceKeepsSemanticBaseline(previousFailure, boundary.sourceHash)
777
+ : (!initialSemanticBaseline && syncCache.hashes[key] === undefined) ||
778
+ syncCache.semanticContracts[key] === true ||
779
+ (previousSemanticHash !== undefined &&
780
+ previousSemanticHash !== boundary.sourceHash));
770
781
  if (enforceBoundary && boundary.errors.length > 0) {
771
782
  inventoryFailures.push(`${key}: proposition-complete ingestion failed: ${boundary.errors.join("; ")}.`);
772
783
  if (!advertisedContract)
@@ -29,6 +29,11 @@ export declare function withStoredRequirementSemantics(input: UpsertInput, prolo
29
29
  * inventory is legacy content sync keeps accepting, so a write that changes
30
30
  * neither keeps working. A write that makes the requirement current, or
31
31
  * changes the prose sync checks, must carry the complete inventory.
32
+ *
33
+ * A requirement the store does not hold (its file failed the last sync, or
34
+ * was written since) is judged by the rule sync applies to that file: it
35
+ * keeps the legacy treatment only when the last sync recorded the file as
36
+ * legacy content or as having compiled with the same prose.
32
37
  */
33
38
  export declare function assertStoredRequirementBoundary(input: UpsertInput, relationships: readonly SemanticRelationship[], prolog: Pick<PrologPort, "query">, staged?: StagedUpsertState, lookup?: StoredEntityLookup): Promise<void>;
34
39
  //# sourceMappingURL=requirement-semantics.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"requirement-semantics.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/requirement-semantics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAE3E,OAAO,EAEL,KAAK,oBAAoB,EAE1B,MAAM,2CAA2C,CAAC;AAEnD,OAAO,EACL,KAAK,kBAAkB,EAExB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAwCjE;;;;;;;;;;;;GAYG;AACH,wBAAsB,8BAA8B,CAClD,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,EACjC,MAAM,CAAC,EAAE,iBAAiB,EAC1B,MAAM,GAAE,kBAAqE,GAC5E,OAAO,CAAC,WAAW,CAAC,CAsCtB;AAuBD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,+BAA+B,CACnD,KAAK,EAAE,WAAW,EAClB,aAAa,EAAE,SAAS,oBAAoB,EAAE,EAC9C,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,EACjC,MAAM,CAAC,EAAE,iBAAiB,EAC1B,MAAM,GAAE,kBAAqE,GAC5E,OAAO,CAAC,IAAI,CAAC,CAmBf"}
1
+ {"version":3,"file":"requirement-semantics.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/requirement-semantics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAE3E,OAAO,EAEL,KAAK,oBAAoB,EAE1B,MAAM,2CAA2C,CAAC;AAEnD,OAAO,EACL,KAAK,kBAAkB,EAExB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAwCjE;;;;;;;;;;;;GAYG;AACH,wBAAsB,8BAA8B,CAClD,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,EACjC,MAAM,CAAC,EAAE,iBAAiB,EAC1B,MAAM,GAAE,kBAAqE,GAC5E,OAAO,CAAC,WAAW,CAAC,CAsCtB;AAkCD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,+BAA+B,CACnD,KAAK,EAAE,WAAW,EAClB,aAAa,EAAE,SAAS,oBAAoB,EAAE,EAC9C,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,EACjC,MAAM,CAAC,EAAE,iBAAiB,EAC1B,MAAM,GAAE,kBAAqE,GAC5E,OAAO,CAAC,IAAI,CAAC,CAwBf"}
@@ -82,6 +82,12 @@ const BOUNDARY_FIELDS = [
82
82
  "text_ref",
83
83
  ...SEMANTIC_CONTRACT_FIELDS,
84
84
  ];
85
+ /** Whether a requirement states an inventory contract sync always checks. */
86
+ function advertisesSemanticContract(properties) {
87
+ return (properties.semantic_inventory_version !== undefined ||
88
+ properties.semantic_source_hash !== undefined ||
89
+ properties.semantic_inventory !== undefined);
90
+ }
85
91
  function boundaryOf(input, properties, relationships) {
86
92
  const payload = { type: input.type, id: input.id, properties };
87
93
  const { receipt } = analyzeSemanticAdvisorInput({
@@ -89,7 +95,7 @@ function boundaryOf(input, properties, relationships) {
89
95
  });
90
96
  return validateSemanticInventoryBoundary(payload, relationships, receipt);
91
97
  }
92
- // implements REQ-kibi-upsert-preserves-requirement-semantics, REQ-kibi-proposition-complete-ingestion
98
+ // implements REQ-kibi-upsert-preserves-requirement-semantics, REQ-kibi-proposition-complete-ingestion, REQ-kibi-uncompiled-source-semantic-baseline
93
99
  /**
94
100
  * An update to a stored requirement is judged as its authored file will read
95
101
  * afterwards: the stored status, prose and proposition ledger with the
@@ -103,6 +109,11 @@ function boundaryOf(input, properties, relationships) {
103
109
  * inventory is legacy content sync keeps accepting, so a write that changes
104
110
  * neither keeps working. A write that makes the requirement current, or
105
111
  * changes the prose sync checks, must carry the complete inventory.
112
+ *
113
+ * A requirement the store does not hold (its file failed the last sync, or
114
+ * was written since) is judged by the rule sync applies to that file: it
115
+ * keeps the legacy treatment only when the last sync recorded the file as
116
+ * legacy content or as having compiled with the same prose.
106
117
  */
107
118
  export async function assertStoredRequirementBoundary(input, relationships, prolog, staged, lookup = storedEntityLookup(prolog, input.id, input.type)) {
108
119
  if (input.type !== "req")
@@ -115,11 +126,19 @@ export async function assertStoredRequirementBoundary(input, relationships, prol
115
126
  if (stored[field] !== undefined)
116
127
  before[field] = stored[field];
117
128
  }
118
- const after = boundaryOf(input, { ...before, ...(input.properties ?? {}) }, relationships);
129
+ const written = { ...before, ...(input.properties ?? {}) };
130
+ const after = boundaryOf(input, written, relationships);
119
131
  if (after.errors.length === 0)
120
132
  return;
121
- const previous = boundaryOf(input, before, relationships);
122
- if (previous.applicable && previous.sourceHash === after.sourceHash)
123
- return;
133
+ if (lookup.keepsSemanticBaseline !== undefined) {
134
+ if (!advertisesSemanticContract(written) &&
135
+ lookup.keepsSemanticBaseline(after.sourceHash))
136
+ return;
137
+ }
138
+ else {
139
+ const previous = boundaryOf(input, before, relationships);
140
+ if (previous.applicable && previous.sourceHash === after.sourceHash)
141
+ return;
142
+ }
124
143
  throw new Error(`Proposition-complete ingestion failed: ${input.id} would be written as a current requirement without a complete proposition inventory (${after.errors.join("; ")}). Run kb_model mode analyze (CLI: semantic-advisor) with id '${input.id}' and its complete semantic_text, then send the returned inventory contract (semantic_inventory, semantic_inventory_version, semantic_source_field, semantic_source_hash, logic_claims) in this kb_upsert, or retire the requirement through a superseding one instead.`);
125
144
  }
@@ -14,6 +14,13 @@ export type StoredEntityLookup = {
14
14
  * rather than the store (an entity the store does not hold yet).
15
15
  */
16
16
  readonly relationships?: readonly Readonly<Record<string, unknown>>[];
17
+ /**
18
+ * For an entity the store does not hold: whether kibi sync will accept its
19
+ * requirement prose (hashing to the given semantic source hash) without a
20
+ * complete inventory. Absent for a stored entity, which is judged by its
21
+ * stored prose instead.
22
+ */
23
+ readonly keepsSemanticBaseline?: (sourceHash: string) => boolean;
17
24
  };
18
25
  /**
19
26
  * One read of the entity an upsert replaces, shared by every step of the
@@ -1 +1 @@
1
- {"version":3,"file":"stored-entity.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/stored-entity.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAE3E;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;AAGhF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,+CAA+C;IAC/C,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACxC,sDAAsD;IACtD,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;IAC7C;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;CACvE,CAAC;AAGF;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,EACjC,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,GACX,kBAAkB,CAsBpB"}
1
+ {"version":3,"file":"stored-entity.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/stored-entity.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAE3E;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;AAGhF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,+CAA+C;IAC/C,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACxC,sDAAsD;IACtD,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;IAC7C;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;IACtE;;;;;OAKG;IACH,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;CAClE,CAAC;AAGF;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,EACjC,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,GACX,kBAAkB,CAsBpB"}
@@ -1,3 +1,4 @@
1
+ import { type SourceExtractionFailure } from "../../commands/sync/cache.js";
1
2
  import type { OperationContext } from "../../public/operations/runtime-types.js";
2
3
  import type { StoredEntityLookup } from "./stored-entity.js";
3
4
  import type { RelationshipInput, UpsertInput } from "./types.js";
@@ -17,6 +18,11 @@ export type UncompiledAuthoredSource = Readonly<{
17
18
  stored: Readonly<Record<string, unknown>>;
18
19
  /** Why kibi sync cannot compile the file as authored; null when it can. */
19
20
  extractionError: string | null;
21
+ /**
22
+ * What the last sync recorded when it could not extract the file; undefined
23
+ * when no sync has failed on it (the file was written since).
24
+ */
25
+ syncFailure: SourceExtractionFailure | undefined;
20
26
  }>;
21
27
  /**
22
28
  * The authored document an upsert of `input` would merge into although the
@@ -1 +1 @@
1
- {"version":3,"file":"uncompiled-source.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/uncompiled-source.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAMjF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEjE;;;GAGG;AAEH,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1C,2EAA2E;IAC3E,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC,CAAC,CAAC;AAMH;;;;;;;GAOG;AAEH,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,WAAW,GACjB,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,CA8C1C;AAED;;;;GAIG;AAEH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,wBAAwB,GAC/B,kBAAkB,CAKpB;AAED;;;;;GAKG;AAEH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,wBAAwB,EAChC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC,SAAS,iBAAiB,EAAE,CAa9B"}
1
+ {"version":3,"file":"uncompiled-source.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/uncompiled-source.ts"],"names":[],"mappings":"AAmBA,OAAO,EACL,KAAK,uBAAuB,EAI7B,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAQjF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEjE;;;GAGG;AAEH,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1C,2EAA2E;IAC3E,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B;;;OAGG;IACH,WAAW,EAAE,uBAAuB,GAAG,SAAS,CAAC;CAClD,CAAC,CAAC;AAqBH;;;;;;;GAOG;AAEH,wBAAsB,4BAA4B,CAChD,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,WAAW,GACjB,OAAO,CAAC,wBAAwB,GAAG,IAAI,CAAC,CAgD1C;AAED;;;;GAIG;AAEH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,wBAAwB,GAC/B,kBAAkB,CAWpB;AAED;;;;;GAKG;AAEH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,wBAAwB,EAChC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC,SAAS,iBAAiB,EAAE,CAa9B"}
@@ -16,9 +16,18 @@
16
16
  along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
  */
18
18
  import path from "node:path";
19
- import { sourceExtractionRemediation } from "../../commands/sync/cache.js";
19
+ import { failedSourceKeepsSemanticBaseline, sourceExtractionFailure, sourceExtractionRemediation, } from "../../commands/sync/cache.js";
20
20
  import { extractFromMarkdownString } from "../../extractors/markdown.js";
21
+ import { resolveBranchAttachment } from "../../utils/branch-resolver.js";
22
+ import { branchStorePath } from "../../utils/branch-store-locator.js";
21
23
  import { authoredFrontmatter, newEntitySourceTarget, renderSourceDocument, } from "./source-authoring.js";
24
+ // implements REQ-kibi-uncompiled-source-semantic-baseline
25
+ function lastSyncFailure(context, relative) {
26
+ const attachment = context.branchAttachment ?? resolveBranchAttachment(context.workspaceRoot);
27
+ if ("error" in attachment)
28
+ return undefined;
29
+ return sourceExtractionFailure(context.workspaceRoot, branchStorePath(context.workspaceRoot, attachment.kbBranch), relative);
30
+ }
22
31
  function errorText(error) {
23
32
  return error instanceof Error ? error.message : String(error);
24
33
  }
@@ -59,6 +68,7 @@ export async function readUncompiledAuthoredSource(context, input) {
59
68
  content,
60
69
  stored: entity,
61
70
  extractionError: null,
71
+ syncFailure: lastSyncFailure(context, relative),
62
72
  };
63
73
  }
64
74
  catch (error) {
@@ -80,6 +90,7 @@ export async function readUncompiledAuthoredSource(context, input) {
80
90
  content,
81
91
  stored: { ...frontmatter, id: input.id, type: input.type },
82
92
  extractionError,
93
+ syncFailure: lastSyncFailure(context, relative),
83
94
  };
84
95
  }
85
96
  }
@@ -90,9 +101,14 @@ export async function readUncompiledAuthoredSource(context, input) {
90
101
  */
91
102
  // implements REQ-kibi-uncompiled-source-visibility
92
103
  export function authoredEntityLookup(source) {
104
+ const failure = source.syncFailure;
93
105
  return {
94
106
  exists: async () => true,
95
107
  entity: async () => source.stored,
108
+ // The next sync judges the file by its last failure record, not by the
109
+ // state the file states now, so the write guard does the same.
110
+ keepsSemanticBaseline: (sourceHash) => failure !== undefined &&
111
+ failedSourceKeepsSemanticBaseline(failure, sourceHash),
96
112
  };
97
113
  }
98
114
  /**
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Prolog goal that switches the child's standard streams and its default
3
+ * file encoding to UTF-8. SWI-Prolog otherwise follows the process locale,
4
+ * and under a POSIX locale every non-ASCII byte read from stdin becomes
5
+ * U+FFFD, which the store then persists.
6
+ */
7
+ export declare const PROLOG_UTF8_STREAMS_GOAL = "set_prolog_flag(encoding, utf8), set_stream(user_input, encoding(utf8)), set_stream(user_output, encoding(utf8)), set_stream(user_error, encoding(utf8))";
8
+ /**
9
+ * Encode a goal for an environment variable. SWI-Prolog decodes environment
10
+ * values with the process locale, so non-ASCII goal text travels as base64
11
+ * of its UTF-8 bytes.
12
+ */
13
+ export declare function encodeGoalForEnv(goal: string): string;
14
+ /** Prolog goal that binds `Atom` to the goal stored by `encodeGoalForEnv`. */
15
+ export declare function decodeGoalFromEnvGoal(variable: string, atom: string): string;
16
+ /**
17
+ * A UTF-8 decoder for one child stream that keeps a character split across
18
+ * two chunks whole instead of decoding each half to U+FFFD.
19
+ */
20
+ export declare function utf8ChunkDecoder(): (chunk: Buffer) => string;
21
+ //# sourceMappingURL=utf8-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utf8-transport.d.ts","sourceRoot":"","sources":["../../src/prolog/utf8-transport.ts"],"names":[],"mappings":"AAqBA;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,6JACuH,CAAC;AAG7J;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAGD,8EAA8E;AAC9E,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5E;AAGD;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAG5D"}
@@ -0,0 +1,49 @@
1
+ /*
2
+ Kibi — repo-local, per-branch, queryable long-term memory for software projects
3
+ Copyright (C) 2026 Piotr Franczyk
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU Affero General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU Affero General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Affero General Public License
16
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+ */
18
+ import { StringDecoder } from "node:string_decoder";
19
+ // implements REQ-prolog-utf8-text
20
+ /**
21
+ * Prolog goal that switches the child's standard streams and its default
22
+ * file encoding to UTF-8. SWI-Prolog otherwise follows the process locale,
23
+ * and under a POSIX locale every non-ASCII byte read from stdin becomes
24
+ * U+FFFD, which the store then persists.
25
+ */
26
+ export const PROLOG_UTF8_STREAMS_GOAL = "set_prolog_flag(encoding, utf8), set_stream(user_input, encoding(utf8)), set_stream(user_output, encoding(utf8)), set_stream(user_error, encoding(utf8))";
27
+ // implements REQ-prolog-utf8-text
28
+ /**
29
+ * Encode a goal for an environment variable. SWI-Prolog decodes environment
30
+ * values with the process locale, so non-ASCII goal text travels as base64
31
+ * of its UTF-8 bytes.
32
+ */
33
+ export function encodeGoalForEnv(goal) {
34
+ return Buffer.from(goal, "utf8").toString("base64");
35
+ }
36
+ // implements REQ-prolog-utf8-text
37
+ /** Prolog goal that binds `Atom` to the goal stored by `encodeGoalForEnv`. */
38
+ export function decodeGoalFromEnvGoal(variable, atom) {
39
+ return `getenv('${variable}', ${atom}Encoded), base64_encoded(${atom}, ${atom}Encoded, [encoding(utf8), as(atom)])`;
40
+ }
41
+ // implements REQ-prolog-utf8-text
42
+ /**
43
+ * A UTF-8 decoder for one child stream that keeps a character split across
44
+ * two chunks whole instead of decoding each half to U+FFFD.
45
+ */
46
+ export function utf8ChunkDecoder() {
47
+ const decoder = new StringDecoder("utf8");
48
+ return (chunk) => decoder.write(chunk);
49
+ }
package/dist/prolog.d.ts CHANGED
@@ -52,6 +52,8 @@ export declare class PrologProcess {
52
52
  private outputOverflowed;
53
53
  private errorBuffer;
54
54
  private errorBufferBytes;
55
+ private decodeOutput;
56
+ private decodeError;
55
57
  private cache;
56
58
  private interactiveQueryTail;
57
59
  private terminationPromise;
@@ -1 +1 @@
1
- {"version":3,"file":"prolog.d.ts","sourceRoot":"","sources":["../src/prolog.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prolog.d.ts","sourceRoot":"","sources":["../src/prolog.ts"],"names":[],"mappings":"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"}
package/dist/prolog.js CHANGED
@@ -26,6 +26,7 @@ import { kibiPackageVersions } from "./package-versions.js";
26
26
  import { writePerformanceTraceEvent } from "./performance-trace.js";
27
27
  import { extractPrologErrorRecord, } from "./prolog/error-terms.js";
28
28
  import { resolveSwipl, swiplChildEnv, } from "./prolog/swipl-resolver.js";
29
+ import { PROLOG_UTF8_STREAMS_GOAL, decodeGoalFromEnvGoal, encodeGoalForEnv, utf8ChunkDecoder, } from "./prolog/utf8-transport.js";
29
30
  const importMetaDir = path.dirname(fileURLToPath(import.meta.url));
30
31
  const DEFAULT_PROLOG_OUTPUT_MAX_BUFFER_BYTES = 8 * 1024 * 1024;
31
32
  const PROLOG_OUTPUT_OVERFLOW_ERROR = "Query exceeded bounded Prolog output capacity (ENOBUFS); narrow the operation or reduce stored entity size";
@@ -106,6 +107,8 @@ export class PrologProcess {
106
107
  outputOverflowed = false;
107
108
  errorBuffer = "";
108
109
  errorBufferBytes = 0;
110
+ decodeOutput = utf8ChunkDecoder();
111
+ decodeError = utf8ChunkDecoder();
109
112
  cache = new Map();
110
113
  interactiveQueryTail = Promise.resolve();
111
114
  terminationPromise = null;
@@ -183,7 +186,7 @@ export class PrologProcess {
183
186
  this.invalidateCache();
184
187
  this.process = spawn(launch.bin, [
185
188
  "-g",
186
- `use_module('${kbPath}'), use_module(library(semweb/rdf_db)), set_prolog_flag(answer_write_options, [max_depth(0), quoted(true)])`,
189
+ `${PROLOG_UTF8_STREAMS_GOAL}, use_module('${kbPath}'), use_module(library(semweb/rdf_db)), set_prolog_flag(answer_write_options, [max_depth(0), quoted(true)])`,
187
190
  "--quiet",
188
191
  ], {
189
192
  detached: process.platform !== "win32",
@@ -196,6 +199,8 @@ export class PrologProcess {
196
199
  },
197
200
  });
198
201
  this.clearQueryBuffers();
202
+ this.decodeOutput = utf8ChunkDecoder();
203
+ this.decodeError = utf8ChunkDecoder();
199
204
  if (!this.process.stdout || !this.process.stderr || !this.process.stdin) {
200
205
  throw new Error("Failed to spawn Prolog process");
201
206
  }
@@ -574,10 +579,11 @@ export class PrologProcess {
574
579
  : `(${goalList.join(", ")})`;
575
580
  const kbModulePath = resolveKbPlPath();
576
581
  const prologGoal = [
582
+ PROLOG_UTF8_STREAMS_GOAL,
577
583
  `use_module('${kbModulePath}')`,
578
584
  "use_module(library(semweb/rdf_db))",
579
585
  "set_prolog_flag(answer_write_options, [max_depth(0), quoted(true)])",
580
- "getenv('KIBI_GOAL', GoalAtom)",
586
+ decodeGoalFromEnvGoal("KIBI_GOAL", "GoalAtom"),
581
587
  "read_term_from_atom(GoalAtom, Goal, [variable_names(Vars)])",
582
588
  kbPath ? "getenv('KIBI_KB_PATH', KBPath), kb_attach(KBPath)" : "true",
583
589
  isBatch ? "WrappedGoal = rdf_transaction(Goal)" : "WrappedGoal = Goal",
@@ -601,7 +607,7 @@ export class PrologProcess {
601
607
  env: {
602
608
  ...process.env,
603
609
  ...launch.env,
604
- KIBI_GOAL: combinedGoal,
610
+ KIBI_GOAL: encodeGoalForEnv(combinedGoal ?? "true"),
605
611
  KIBI_RUNTIME_NAME: runtimeName,
606
612
  KIBI_RUNTIME_VERSION: runtimeVersion,
607
613
  KIBI_PACKAGE_VERSIONS: packageVersions,
@@ -627,13 +633,16 @@ export class PrologProcess {
627
633
  let settled = false;
628
634
  let closed = false;
629
635
  let termination = null;
636
+ const decodeStdout = utf8ChunkDecoder();
637
+ const decodeStderr = utf8ChunkDecoder();
630
638
  const appendChunk = (chunk, target) => {
631
639
  if (outputOverflowed)
632
640
  return;
633
641
  const bytes = target === "stdout" ? outputBytes : errorBytes;
634
642
  const remaining = this.maxOutputBytes - bytes;
643
+ const decode = target === "stdout" ? decodeStdout : decodeStderr;
635
644
  if (chunk.byteLength > remaining) {
636
- const clipped = chunk.subarray(0, Math.max(0, remaining)).toString();
645
+ const clipped = decode(chunk.subarray(0, Math.max(0, remaining)));
637
646
  if (target === "stdout")
638
647
  stdout += clipped;
639
648
  else
@@ -643,11 +652,11 @@ export class PrologProcess {
643
652
  return;
644
653
  }
645
654
  if (target === "stdout") {
646
- stdout += chunk.toString();
655
+ stdout += decode(chunk);
647
656
  outputBytes += chunk.byteLength;
648
657
  }
649
658
  else {
650
- stderr += chunk.toString();
659
+ stderr += decode(chunk);
651
660
  errorBytes += chunk.byteLength;
652
661
  }
653
662
  };
@@ -749,12 +758,12 @@ export class PrologProcess {
749
758
  return;
750
759
  const remaining = this.maxOutputBytes - this.outputBufferBytes;
751
760
  if (chunk.byteLength > remaining) {
752
- this.outputBuffer += chunk.subarray(0, remaining).toString();
761
+ this.outputBuffer += this.decodeOutput(chunk.subarray(0, remaining));
753
762
  this.outputBufferBytes = this.maxOutputBytes;
754
763
  this.outputOverflowed = true;
755
764
  return;
756
765
  }
757
- this.outputBuffer += chunk.toString();
766
+ this.outputBuffer += this.decodeOutput(chunk);
758
767
  this.outputBufferBytes += chunk.byteLength;
759
768
  this.wakeOutputWaiter();
760
769
  }
@@ -763,12 +772,12 @@ export class PrologProcess {
763
772
  return;
764
773
  const remaining = this.maxOutputBytes - this.errorBufferBytes;
765
774
  if (chunk.byteLength > remaining) {
766
- this.errorBuffer += chunk.subarray(0, remaining).toString();
775
+ this.errorBuffer += this.decodeError(chunk.subarray(0, remaining));
767
776
  this.errorBufferBytes = this.maxOutputBytes;
768
777
  this.outputOverflowed = true;
769
778
  return;
770
779
  }
771
- this.errorBuffer += chunk.toString();
780
+ this.errorBuffer += this.decodeError(chunk);
772
781
  this.errorBufferBytes += chunk.byteLength;
773
782
  this.wakeOutputWaiter();
774
783
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kibi-cli",
3
- "version": "2.26.2",
3
+ "version": "2.26.3",
4
4
  "type": "module",
5
5
  "description": "Kibi CLI for knowledge base management",
6
6
  "engines": {