kibi-cli 2.28.1 → 2.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/bin/kibi +12 -1
  2. package/dist/cli-command.d.ts +3 -0
  3. package/dist/cli-command.d.ts.map +1 -1
  4. package/dist/cli-command.js +11 -0
  5. package/dist/cli-operation-metadata.d.ts +8 -8
  6. package/dist/cli-operation-metadata.js +8 -8
  7. package/dist/cli-register-reporting.d.ts.map +1 -1
  8. package/dist/cli-register-reporting.js +12 -0
  9. package/dist/cli.d.ts.map +1 -1
  10. package/dist/cli.js +5 -2
  11. package/dist/commands/check.d.ts.map +1 -1
  12. package/dist/commands/check.js +8 -1
  13. package/dist/commands/engine.d.ts.map +1 -1
  14. package/dist/commands/engine.js +26 -2
  15. package/dist/commands/signoff.d.ts +37 -0
  16. package/dist/commands/signoff.d.ts.map +1 -0
  17. package/dist/commands/signoff.js +152 -0
  18. package/dist/commands/sync.d.ts +10 -0
  19. package/dist/commands/sync.d.ts.map +1 -1
  20. package/dist/commands/sync.js +67 -3
  21. package/dist/engine.d.ts +11 -1
  22. package/dist/engine.d.ts.map +1 -1
  23. package/dist/engine.js +120 -34
  24. package/dist/operations/modeling/predicate-applicability.d.ts +5 -1
  25. package/dist/operations/modeling/predicate-applicability.d.ts.map +1 -1
  26. package/dist/operations/modeling/predicate-applicability.js +35 -2
  27. package/dist/operations/modeling/suggest-predicates.d.ts.map +1 -1
  28. package/dist/operations/modeling/suggest-predicates.js +3 -1
  29. package/dist/operations/mutation/contradictions.d.ts +7 -5
  30. package/dist/operations/mutation/contradictions.d.ts.map +1 -1
  31. package/dist/operations/mutation/contradictions.js +8 -6
  32. package/dist/operations/mutation/source-authoring.d.ts +15 -0
  33. package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
  34. package/dist/operations/mutation/source-authoring.js +19 -7
  35. package/dist/operations/mutation/types.d.ts +5 -0
  36. package/dist/operations/mutation/types.d.ts.map +1 -1
  37. package/dist/operations/mutation/upsert.d.ts +14 -0
  38. package/dist/operations/mutation/upsert.d.ts.map +1 -1
  39. package/dist/operations/mutation/upsert.js +42 -36
  40. package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
  41. package/dist/operations/mutation/validate-upsert.js +61 -37
  42. package/dist/prolog/error-terms.d.ts.map +1 -1
  43. package/dist/prolog/error-terms.js +15 -9
  44. package/dist/prolog/store-lock.d.ts +11 -0
  45. package/dist/prolog/store-lock.d.ts.map +1 -1
  46. package/dist/prolog/store-lock.js +48 -1
  47. package/dist/public/operations/catalog.d.ts +29 -8
  48. package/dist/public/operations/catalog.d.ts.map +1 -1
  49. package/dist/public/operations/contracts.d.ts.map +1 -1
  50. package/dist/public/operations/contracts.js +2 -0
  51. package/dist/public/operations/specs/bootstrap.d.ts +1 -1
  52. package/dist/public/operations/specs/bootstrap.js +1 -1
  53. package/dist/public/operations/specs/composite.d.ts +1 -1
  54. package/dist/public/operations/specs/composite.js +1 -1
  55. package/dist/public/operations/specs/discovery.d.ts +1 -1
  56. package/dist/public/operations/specs/discovery.js +1 -1
  57. package/dist/public/operations/specs/impact-review-preparation.d.ts +2 -1
  58. package/dist/public/operations/specs/impact-review-preparation.d.ts.map +1 -1
  59. package/dist/public/operations/specs/impact-review-preparation.js +2 -1
  60. package/dist/public/operations/specs/planning.d.ts +1 -1
  61. package/dist/public/operations/specs/planning.js +1 -1
  62. package/dist/public/operations/specs/reporting.d.ts +23 -3
  63. package/dist/public/operations/specs/reporting.d.ts.map +1 -1
  64. package/dist/public/operations/specs/reporting.js +97 -21
  65. package/dist/public/skills/kibi-commit-review/SKILL.md +125 -0
  66. package/dist/public/skills/kibi-commit-review/resources/staged-gate.md +98 -0
  67. package/dist/public/skills/kibi-decisions/SKILL.md +130 -0
  68. package/dist/public/skills/kibi-decisions/resources/decision-records.md +142 -0
  69. package/dist/public/skills/kibi-decisions/resources/signoff-views.md +66 -0
  70. package/dist/public/skills/kibi-freshness/SKILL.md +2 -0
  71. package/dist/public/skills/kibi-traceability/SKILL.md +4 -0
  72. package/dist/public/skills/kibi-usage/SKILL.md +20 -15
  73. package/dist/signoff/collect.d.ts +39 -0
  74. package/dist/signoff/collect.d.ts.map +1 -0
  75. package/dist/signoff/collect.js +398 -0
  76. package/dist/signoff/html.d.ts +4 -0
  77. package/dist/signoff/html.d.ts.map +1 -0
  78. package/dist/signoff/html.js +210 -0
  79. package/dist/signoff/markdown.d.ts +20 -0
  80. package/dist/signoff/markdown.d.ts.map +1 -0
  81. package/dist/signoff/markdown.js +203 -0
  82. package/dist/signoff/model.d.ts +134 -0
  83. package/dist/signoff/model.d.ts.map +1 -0
  84. package/dist/signoff/model.js +138 -0
  85. package/dist/traceability/commit-amend.d.ts +7 -0
  86. package/dist/traceability/commit-amend.d.ts.map +1 -0
  87. package/dist/traceability/commit-amend.js +85 -0
  88. package/dist/traceability/staged-inventory-drift.d.ts +12 -2
  89. package/dist/traceability/staged-inventory-drift.d.ts.map +1 -1
  90. package/dist/traceability/staged-inventory-drift.js +22 -5
  91. package/package.json +2 -2
  92. package/src/public/operations/contracts.ts +2 -0
  93. package/src/public/operations/specs/bootstrap.ts +1 -1
  94. package/src/public/operations/specs/composite.ts +1 -1
  95. package/src/public/operations/specs/discovery.ts +1 -1
  96. package/src/public/operations/specs/impact-review-preparation.ts +3 -1
  97. package/src/public/operations/specs/planning.ts +1 -1
  98. package/src/public/operations/specs/reporting.ts +109 -21
  99. package/src/public/skills/kibi-commit-review/SKILL.md +125 -0
  100. package/src/public/skills/kibi-commit-review/resources/staged-gate.md +98 -0
  101. package/src/public/skills/kibi-decisions/SKILL.md +130 -0
  102. package/src/public/skills/kibi-decisions/resources/decision-records.md +142 -0
  103. package/src/public/skills/kibi-decisions/resources/signoff-views.md +66 -0
  104. package/src/public/skills/kibi-freshness/SKILL.md +2 -0
  105. package/src/public/skills/kibi-traceability/SKILL.md +4 -0
  106. package/src/public/skills/kibi-usage/SKILL.md +20 -15
@@ -873,9 +873,15 @@ export function isUntrackedByGit(workspaceRoot, relative) {
873
873
  return error.status === 1;
874
874
  }
875
875
  }
876
- export async function writeSourceForUpsert(input, entity, existing, context, sourceDocumentOverride) {
877
- if (!context?.fs)
878
- return null;
876
+ // implements REQ-kibi-operation-interface-parity
877
+ /**
878
+ * The authored document an upsert publishes, resolved and rendered without
879
+ * writing: the target path (with its containment checks), the current bytes
880
+ * and the bytes the write would publish. writeSourceForUpsert publishes
881
+ * exactly this, and a kb_upsert dry run renders it so a path or format the
882
+ * write would refuse is refused by the dry run too.
883
+ */
884
+ export async function renderSourceWrite(input, entity, existing, context, sourceDocumentOverride) {
879
885
  const absolute = sourcePath(context, input, entity, existing);
880
886
  const relative = path
881
887
  .relative(context.workspaceRoot, absolute)
@@ -887,10 +893,6 @@ export async function writeSourceForUpsert(input, entity, existing, context, sou
887
893
  catch {
888
894
  before = undefined;
889
895
  }
890
- // Freshness compares file times with the compiled snapshot, so restoring
891
- // the bytes alone would still make an untouched entity read as stale after
892
- // a rolled-back write. Snapshot the times before the publication below.
893
- const priorTimes = before === undefined ? null : readFileTimes(absolute);
894
896
  // Proof-receipt ingest supplies pre-patched bytes so unrelated frontmatter
895
897
  // keeps its authored formatting (and the workspace snapshot stays stable).
896
898
  // Only valid when the document already exists; a new document still needs
@@ -898,6 +900,16 @@ export async function writeSourceForUpsert(input, entity, existing, context, sou
898
900
  const after = before !== undefined && sourceDocumentOverride !== undefined
899
901
  ? sourceDocumentOverride
900
902
  : renderSourceDocument(input, entity, before, relative);
903
+ return { absolute, relative, before, after };
904
+ }
905
+ export async function writeSourceForUpsert(input, entity, existing, context, sourceDocumentOverride) {
906
+ if (!context?.fs)
907
+ return null;
908
+ const { absolute, relative, before, after } = await renderSourceWrite(input, entity, existing, { ...context, fs: context.fs }, sourceDocumentOverride);
909
+ // Freshness compares file times with the compiled snapshot, so restoring
910
+ // the bytes alone would still make an untouched entity read as stale after
911
+ // a rolled-back write. Snapshot the times before the publication below.
912
+ const priorTimes = before === undefined ? null : readFileTimes(absolute);
901
913
  await context.fs.mkdir(path.dirname(absolute));
902
914
  const temporary = `${absolute}.kibi-source-${process.pid}-${randomUUID()}`;
903
915
  try {
@@ -105,6 +105,11 @@ export type ValidateUpsertPayload = {
105
105
  readonly warnings: readonly string[];
106
106
  readonly semanticAdvisor: SemanticAdvisorReceipt | null;
107
107
  readonly normalizedPreview: Readonly<Record<string, unknown>> | null;
108
+ /**
109
+ * When the payload is invalid and the write would refuse it with a coded
110
+ * error (for example DOCUMENT_PATH_REQUIRED): that code.
111
+ */
112
+ readonly errorCode?: string;
108
113
  /** Planned fact ids staged ahead of the payload, in order. */
109
114
  readonly stagedFacts?: readonly string[];
110
115
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAC3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAGrD,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAGlE,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACvD,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACtD,QAAQ,CAAC,QAAQ,CAAC,EAAE;QAClB,iDAAiD;QACjD,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QACvB,gIAAgI;QAChI,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,8DAA8D;IAC9D,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACpD,QAAQ,CAAC,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAC3C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAGF,wDAAwD;AACxD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACvD,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;CACvD,CAAC;AAGF;;;;;GAKG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,0DAA0D;IAC1D,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1E,0DAA0D;IAC1D,QAAQ,CAAC,aAAa,EAAE,SAAS,iBAAiB,EAAE,CAAC;CACtD,CAAC;AAGF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,QAAQ,CAAC,aAAa,EAAE,SAAS,iBAAiB,EAAE,CAAC;CACtD,CAAC;AAGF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,+EAA+E;IAC/E,QAAQ,CAAC,eAAe,CAAC,EAAE,sBAAsB,CAAC;IAClD;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,wBAAwB,CAAC;IAC3C,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS;QACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;KAC3B,EAAE,CAAC;IACJ,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS;QAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;QACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;KAC5B,EAAE,CAAC;IACJ,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS;QAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;QACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QAClC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;KAC3B,EAAE,CAAC;IACJ,QAAQ,CAAC,kBAAkB,CAAC,EAAE;QAC5B,QAAQ,CAAC,OAAO,EAAE,aAAa,GAAG,SAAS,CAAC;QAC5C,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;QAChC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;KACnC,CAAC;IACF,QAAQ,CAAC,cAAc,CAAC,EAAE,oBAAoB,CAAC;CAChD,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD,QAAQ,CAAC,aAAa,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACrD,QAAQ,CAAC,sBAAsB,EAAE,OAAO,CAAC;IACzC,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,cAAc,GAAG,aAAa,GAAG,WAAW,CAAC;IAC1E,QAAQ,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,SAAS,mBAAmB,EAAE,CAAC,CAAC;CAClE,CAAC;AAGF,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,eAAe,EAAE,sBAAsB,GAAG,IAAI,CAAC;IACxD,QAAQ,CAAC,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IACrE;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,8DAA8D;IAC9D,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC;QACzB,UAAU,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;QACzD,OAAO,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;QACtD,SAAS,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;KACzD,CAAC,CAAC;CACJ,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS;QAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;KACrB,EAAE,CAAC;IACJ,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,wEAAwE;IACxE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,wEAAwE;IACxE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,aAAa,GACrB,eAAe,GACf,uBAAuB,GACvB,cAAc,GACd,SAAS,CAAC;AAEd,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IACxC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;IACpE,QAAQ,CAAC,oBAAoB,CAAC,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACnE,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,8EAA8E;IAC9E,QAAQ,CAAC,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,iCAAiC;IACjC,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC;IACvB,gDAAgD;IAChD,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC;QAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;QACjC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;QAChC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;KACjC,CAAC,CAAC;IACH,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,MAAM,CAAC,EAAE,wBAAwB,CAAC;IAC3C,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,QAAQ,CAAC;QACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;QACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;QAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC,EAAE,CAAC;IACL,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS;QAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;QACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;QAClC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;KAC3B,EAAE,CAAC;IACJ,QAAQ,CAAC,YAAY,CAAC,EAAE;QACtB,QAAQ,CAAC,OAAO,EAAE,8BAA8B,CAAC;QACjD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;QACtC,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;QAC/D,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS;YAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;YACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;YAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;YACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;YAClC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;SACxB,EAAE,CAAC;QACJ,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;KACxC,CAAC;CACH,CAAC"}
@@ -82,5 +82,19 @@ export type UpsertExecutionOptions = Readonly<{
82
82
  */
83
83
  readonly deferCompiledCommit?: boolean;
84
84
  }>;
85
+ /**
86
+ * Whether a source-first upsert publishes an authored document, and the
87
+ * stored entity it updates (undefined for a create). Null when the write
88
+ * touches no document: no filesystem, a compiled-only runtime, or an
89
+ * existing entity whose runtime source (mcp://, test://, etc.) has no
90
+ * tracked document and the caller names none. A new entity always gets a
91
+ * document in a filesystem-capable runtime: writeSourceForUpsert emits the
92
+ * typed DOCUMENT_PATH_REQUIRED request when configuration has zero or
93
+ * multiple writable targets, rather than silently creating compiled-only
94
+ * state. The write and its dry run share this decision.
95
+ */
96
+ export declare function sourceWriteScope(input: UpsertInput, context: OperationContext): Promise<{
97
+ readonly existing: Readonly<Record<string, unknown>> | undefined;
98
+ } | null>;
85
99
  export declare function executeUpsert(input: UpsertInput, context: OperationContext, options?: UpsertExecutionOptions): Promise<OperationResult<UpsertPayload>>;
86
100
  //# sourceMappingURL=upsert.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"upsert.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/upsert.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"upsert.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/upsert.ts"],"names":[],"mappings":"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"}
@@ -356,6 +356,31 @@ async function resolveUpsertFirmness(input, staged, lookup) {
356
356
  };
357
357
  }
358
358
  // implements REQ-kibi-operation-interface-parity
359
+ /**
360
+ * Whether a source-first upsert publishes an authored document, and the
361
+ * stored entity it updates (undefined for a create). Null when the write
362
+ * touches no document: no filesystem, a compiled-only runtime, or an
363
+ * existing entity whose runtime source (mcp://, test://, etc.) has no
364
+ * tracked document and the caller names none. A new entity always gets a
365
+ * document in a filesystem-capable runtime: writeSourceForUpsert emits the
366
+ * typed DOCUMENT_PATH_REQUIRED request when configuration has zero or
367
+ * multiple writable targets, rather than silently creating compiled-only
368
+ * state. The write and its dry run share this decision.
369
+ */
370
+ export async function sourceWriteScope(input, context) {
371
+ if (context.fs === undefined ||
372
+ context.sourceFirst === false ||
373
+ context.prolog === undefined)
374
+ return null;
375
+ const existing = (await loadEntities(context.prolog, { id: input.id, type: input.type }))[0];
376
+ const existingSource = typeof existing?.source === "string" ? existing.source : undefined;
377
+ if (input.document !== undefined ||
378
+ existingSource?.match(/\.(?:md|mdx|ya?ml|json)$/i) ||
379
+ existing === undefined)
380
+ return { existing };
381
+ return null;
382
+ }
383
+ // implements REQ-kibi-operation-interface-parity
359
384
  /**
360
385
  * A dry run is the former kb_validate_upsert preflight on the kb_upsert
361
386
  * surface: the same validation and semantic advisor receipt, no KB or
@@ -432,42 +457,23 @@ export async function executeUpsert(input, context, options = {}) {
432
457
  });
433
458
  relationshipCount = validated.relationships.length;
434
459
  semanticAdvisor = semantic.receipt;
435
- if (context.fs !== undefined && context.sourceFirst !== false) {
436
- const existingRows = await loadEntities(prolog, {
437
- id: input.id,
438
- type: input.type,
439
- });
440
- const existing = existingRows[0];
441
- const existingSource = existing !== undefined && typeof existing.source === "string"
442
- ? existing.source
443
- : undefined;
444
- // Existing non-authored runtime sources (mcp://, test://, etc.) have no
445
- // tracked document to update unless the caller explicitly supplies one;
446
- // new entities are required to choose a source target in this
447
- // filesystem-capable context.
448
- if (input.document !== undefined ||
449
- existingSource?.match(/\.(?:md|mdx|ya?ml|json)$/i) ||
450
- // A filesystem-capable runtime is source-first for every new entity.
451
- // writeSourceForUpsert emits the typed DOCUMENT_PATH_REQUIRED request
452
- // when configuration has zero or multiple writable targets, rather
453
- // than silently creating compiled-only state.
454
- existing === undefined) {
455
- sourceWrite = await writeSourceForUpsert(input, validated.entity, existing, context, options.sourceDocumentOverride);
456
- if (sourceWrite !== null) {
457
- const sourceStep = sourceWrite;
458
- saga.add({
459
- name: "authored-source",
460
- rollback: () => sourceStep.rollback(),
461
- onError: "capture",
462
- });
463
- // The authored path is the entity's canonical identity. Runtime
464
- // transport provenance (mcp://...) must never survive a source-first
465
- // write or a later delete/sync cycle.
466
- commitEntity = {
467
- ...validated.entity,
468
- source: sourceWrite.receipt.path,
469
- };
470
- }
460
+ const sourceScope = await sourceWriteScope(input, context);
461
+ if (sourceScope !== null) {
462
+ sourceWrite = await writeSourceForUpsert(input, validated.entity, sourceScope.existing, context, options.sourceDocumentOverride);
463
+ if (sourceWrite !== null) {
464
+ const sourceStep = sourceWrite;
465
+ saga.add({
466
+ name: "authored-source",
467
+ rollback: () => sourceStep.rollback(),
468
+ onError: "capture",
469
+ });
470
+ // The authored path is the entity's canonical identity. Runtime
471
+ // transport provenance (mcp://...) must never survive a source-first
472
+ // write or a later delete/sync cycle.
473
+ commitEntity = {
474
+ ...validated.entity,
475
+ source: sourceWrite.receipt.path,
476
+ };
471
477
  }
472
478
  }
473
479
  // Relationship shards are canonical source artifacts. Patch them before
@@ -1 +1 @@
1
- {"version":3,"file":"validate-upsert.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/validate-upsert.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,gBAAgB,EAEjB,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAWxE,OAAO,KAAK,EAIV,WAAW,EACX,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAiPpB;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,qBAAqB,CAAC,CAAC,CAkHjD"}
1
+ {"version":3,"file":"validate-upsert.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/validate-upsert.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,gBAAgB,EAEjB,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAWxE,OAAO,KAAK,EAIV,WAAW,EACX,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAqPpB;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,qBAAqB,CAAC,CAAC,CAmIjD"}
@@ -1,13 +1,13 @@
1
1
  // implements REQ-kibi-operation-interface-parity
2
+ import { codedErrorOf } from "../../cli-errors.js";
2
3
  import { escapeAtom } from "../../prolog/codec.js";
3
- import { loadEntities } from "../../public/operations/discovery-entities.js";
4
4
  import { entityIdStyleWarnings } from "../../utils/entity-id-style.js";
5
5
  import { entityContextWarnings } from "./context-warning.js";
6
6
  import { buildUpsertContradictionPreviewGoal, buildWhatIfAnalysisGoal, formatUpsertError, } from "./contradictions.js";
7
7
  import { validateRelationshipSources } from "./relationships.js";
8
- import { canonicalSourcePath } from "./source-authoring.js";
8
+ import { canonicalSourcePath, renderSourceWrite } from "./source-authoring.js";
9
9
  import { validateSymbolGranularity } from "./symbol-granularity.js";
10
- import { analyzeUpsertSemantics, validateAppendOnlyProofReceipts, validateUpsertForCommit, } from "./upsert.js";
10
+ import { analyzeUpsertSemantics, sourceWriteScope, validateAppendOnlyProofReceipts, validateUpsertForCommit, } from "./upsert.js";
11
11
  import { validateUpsertInput } from "./validation.js";
12
12
  import { symbolCoverageWarnings } from "./warnings.js";
13
13
  import { isBlockingWitness, parseWhatIfAnalysis } from "./what-if.js";
@@ -18,49 +18,53 @@ async function entityExists(prolog, id) {
18
18
  }
19
19
  // implements REQ-kibi-operation-interface-parity, REQ-kb-entity-body-context
20
20
  /**
21
- * The authored document a real kb_upsert would update, resolved with the
22
- * write's own rules (stored authored source, else the canonical lane path).
23
- * The preview entity's `source` is the runtime marker, so without this the
24
- * context warning would judge the statement instead of the existing body the
25
- * write preserves. Undefined when the write would not touch a document.
21
+ * The authored document a real kb_upsert would update, resolved and rendered
22
+ * with the write's own rules (sourceWriteScope and renderSourceWrite) but
23
+ * never written. A path or format the write would refuse
24
+ * (DOCUMENT_PATH_REQUIRED, SOURCE_PATH_INVALID, SOURCE_FORMAT_UNSUPPORTED)
25
+ * throws the write's own error. The preview entity's `source` is the runtime
26
+ * marker, so the returned path lets the context warning judge the existing
27
+ * body the write preserves. Undefined when the write would not touch a
28
+ * document.
26
29
  */
27
- async function previewDocumentPath(input, entity, context) {
28
- if (context.fs === undefined || context.sourceFirst === false) {
30
+ async function previewSourceWrite(input, entity, context) {
31
+ const fs = context.fs;
32
+ if (fs === undefined || context.sourceFirst === false)
29
33
  return undefined;
30
- }
31
- try {
32
- const existing = context.prolog === undefined
33
- ? undefined
34
- : (await loadEntities(context.prolog, {
35
- id: input.id,
36
- type: input.type,
37
- }))[0];
38
- const existingSource = typeof existing?.source === "string" ? existing.source : undefined;
39
- if (input.document === undefined &&
40
- existing !== undefined &&
41
- !existingSource?.match(/\.(?:md|mdx|ya?ml|json)$/i)) {
34
+ if (context.prolog === undefined) {
35
+ // No store, so no write either: only locate the document for the
36
+ // context warning.
37
+ try {
38
+ return canonicalSourcePath(context, input, entity);
39
+ }
40
+ catch {
42
41
  return undefined;
43
42
  }
44
- return canonicalSourcePath(context, input, entity, existing);
45
43
  }
46
- catch {
44
+ const scope = await sourceWriteScope(input, context);
45
+ if (scope === null)
47
46
  return undefined;
48
- }
47
+ const { relative } = await renderSourceWrite(input, entity, scope.existing, {
48
+ ...context,
49
+ fs,
50
+ });
51
+ return relative;
49
52
  }
50
53
  // implements REQ-kibi-operation-interface-parity, REQ-kibi-truthful-consistency
51
54
  /**
52
- * The commit-time contradiction check, run against a staged and rolled-back
53
- * copy of the store. Only a `req` commit runs it (facts and scenarios never
54
- * do), and `_skipContradictionCheck` skips it at commit, so the preview skips
55
- * it too. A refusal carries the same message the commit would raise.
55
+ * The commit goal's own refusal rules, run against a staged and rolled-back
56
+ * copy of the store for every entity type: a relationship whose endpoint
57
+ * does not exist, an invalid relationship direction, a symbol mixing
58
+ * executable_for with implements/covered_by, and the requirement
59
+ * contradiction check (only a `req` commit runs it, and
60
+ * `_skipContradictionCheck` skips it at commit and here alike). A refusal
61
+ * carries the same message the commit would raise.
56
62
  */
57
- async function previewContradictions(prolog, input, entity, relationships) {
58
- if (input.type !== "req" || input._skipContradictionCheck === true)
59
- return;
63
+ async function previewCommit(prolog, input, entity, relationships) {
60
64
  const preview = await prolog.query(buildUpsertContradictionPreviewGoal({
61
65
  entity,
62
66
  relationships,
63
- skipContradictionCheck: false,
67
+ skipContradictionCheck: input._skipContradictionCheck === true,
64
68
  }));
65
69
  if (!preview.success) {
66
70
  throw new Error(formatUpsertError(input.id, preview.error, preview.errorRecord));
@@ -167,6 +171,12 @@ async function validateWithoutStore(input, context) {
167
171
  });
168
172
  return { entity: validated.entity, semantic };
169
173
  }
174
+ function isModuleLoadFailure(error) {
175
+ if (!(error instanceof Error))
176
+ return false;
177
+ const code = error.code;
178
+ return code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND";
179
+ }
170
180
  // implements REQ-kibi-operation-interface-parity, REQ-kibi-truthful-consistency
171
181
  /**
172
182
  * kb_upsert dryRun:true (and the former kb_validate_upsert preflight). With a
@@ -181,14 +191,20 @@ export async function executeValidateUpsert(input, context) {
181
191
  let whatIf;
182
192
  let stagedFacts;
183
193
  let relationships = input.relationships ?? [];
194
+ let targetPath;
184
195
  const { entity, semantic } = context.prolog !== undefined
185
196
  ? await stagePlannedFacts(input, context).then(async (facts) => {
186
197
  const result = await validateUpsertForCommit(input, context, facts === null ? {} : { staged: facts.staged });
187
- // The commit goal checks requirement contradictions after the
188
- // validations above; a dry run previews that stage as well, so
198
+ // The write publishes the authored document before its commit
199
+ // goal; render it (without writing) in the same order, so a
200
+ // source refusal surfaces here exactly as the write raises it.
201
+ targetPath = await previewSourceWrite(input, result.validated.entity, context);
202
+ // The commit goal refuses missing relationship endpoints, mixed
203
+ // symbol roles and requirement contradictions after the
204
+ // validations above; a dry run previews that goal as well, so
189
205
  // "valid" means the commit would not refuse the write.
190
206
  if (facts === null) {
191
- await previewContradictions(context.prolog, input, result.validated.entity, result.validated.relationships);
207
+ await previewCommit(context.prolog, input, result.validated.entity, result.validated.relationships);
192
208
  }
193
209
  else {
194
210
  stagedFacts = [...facts.staged.entities.keys()];
@@ -201,6 +217,8 @@ export async function executeValidateUpsert(input, context) {
201
217
  };
202
218
  })
203
219
  : await validateWithoutStore(input, context);
220
+ if (context.prolog === undefined)
221
+ targetPath = await previewSourceWrite(input, entity, context);
204
222
  // Style warnings apply only to entities this upsert would create, so the
205
223
  // existence read happens only when the ID actually has a style issue.
206
224
  const candidateIdStyleWarnings = entityIdStyleWarnings({
@@ -225,7 +243,7 @@ export async function executeValidateUpsert(input, context) {
225
243
  ...coverageWarnings,
226
244
  ...idStyleWarnings,
227
245
  ...entityContextWarnings(input, entity, context.workspaceRoot, {
228
- targetPath: await previewDocumentPath(input, entity, context),
246
+ targetPath,
229
247
  }),
230
248
  ],
231
249
  semanticAdvisor: semantic.receipt,
@@ -247,13 +265,19 @@ export async function executeValidateUpsert(input, context) {
247
265
  };
248
266
  }
249
267
  catch (error) {
268
+ // A module that fails to load is a broken installation, not a property of
269
+ // the payload: report it as a tool failure instead of an invalid payload.
270
+ if (isModuleLoadFailure(error))
271
+ throw error;
250
272
  const message = error instanceof Error ? error.message : String(error);
273
+ const errorCode = codedErrorOf(error)?.code;
251
274
  const payload = {
252
275
  valid: false,
253
276
  errors: [message],
254
277
  warnings: [],
255
278
  semanticAdvisor: null,
256
279
  normalizedPreview: null,
280
+ ...(errorCode !== undefined ? { errorCode } : {}),
257
281
  };
258
282
  return {
259
283
  content: [
@@ -1 +1 @@
1
- {"version":3,"file":"error-terms.d.ts","sourceRoot":"","sources":["../../src/prolog/error-terms.ts"],"names":[],"mappings":"AAoBA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,wBAAwB,oBAAoB,CAAC;AAG1D,MAAM,MAAM,eAAe,GACvB,gBAAgB,GAChB,cAAc,GACd,mBAAmB,GACnB,kBAAkB,GAClB,sBAAsB,GACtB,eAAe,GACf,kBAAkB,CAAC;AAGvB,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAGH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAGH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,KAAK,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC3B,YAAY,CAAC,EAAE,uBAAuB,CAAC;IACvC,SAAS,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC3C,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,yEAAyE;AAEzE,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,GACX,iBAAiB,GAAG,IAAI,CAK1B;AAED,kFAAkF;AAElF,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,GACf,iBAAiB,GAAG,IAAI,CAsG1B"}
1
+ {"version":3,"file":"error-terms.d.ts","sourceRoot":"","sources":["../../src/prolog/error-terms.ts"],"names":[],"mappings":"AAqBA;;;;;;;;;;GAUG;AAEH,eAAO,MAAM,wBAAwB,oBAAoB,CAAC;AAG1D,MAAM,MAAM,eAAe,GACvB,gBAAgB,GAChB,cAAc,GACd,mBAAmB,GACnB,kBAAkB,GAClB,sBAAsB,GACtB,eAAe,GACf,kBAAkB,CAAC;AAGvB,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAGH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAGH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,KAAK,EAAE,oBAAoB,GAAG,IAAI,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC3B,YAAY,CAAC,EAAE,uBAAuB,CAAC;IACvC,SAAS,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC3C,WAAW,CAAC,EAAE,uBAAuB,CAAC;CACvC,CAAC,CAAC;AAEH,yEAAyE;AAEzE,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,GACX,iBAAiB,GAAG,IAAI,CAK1B;AAED,kFAAkF;AAElF,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,GACf,iBAAiB,GAAG,IAAI,CAsG1B"}
@@ -16,6 +16,7 @@
16
16
  along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
  */
18
18
  import { splitTopLevelGeneral } from "./codec.js";
19
+ import { describeLockHolderPid } from "./store-lock.js";
19
20
  /**
20
21
  * Structured transport for Prolog errors.
21
22
  *
@@ -88,7 +89,7 @@ export function parsePrologErrorTerm(termText) {
88
89
  const holder = detail.owner;
89
90
  const holderSummary = holder === null
90
91
  ? "an unidentified holder"
91
- : `pid ${holder.pid ?? "?"}${holder.workspaceRoot !== undefined ? ` for ${holder.workspaceRoot}` : ""}${holder.startedAt !== undefined ? ` since ${holder.startedAt}` : ""}`;
92
+ : `${holder.pid === undefined ? "pid ?" : describeLockHolderPid(holder.pid)}${holder.workspaceRoot !== undefined ? ` for ${holder.workspaceRoot}` : ""}${holder.startedAt !== undefined ? ` since ${holder.startedAt}` : ""}`;
92
93
  return {
93
94
  code: "permission_denied",
94
95
  storeLocked: detail,
@@ -319,16 +320,21 @@ function parseEntityRole(message) {
319
320
  return "target";
320
321
  return undefined;
321
322
  }
322
- /** Strip SWI quoted-atom quoting and unescape standard character escapes. */
323
+ const PROLOG_ESCAPES = { n: "\n", t: "\t" };
324
+ /**
325
+ * Strip SWI quoted-atom or string quoting and unescape standard character
326
+ * escapes. Strings matter for store_locked: kb.pl reads the owner journal
327
+ * with read_file_to_string, so the owner arrives double-quoted.
328
+ */
323
329
  function unquoteAtom(value) {
324
330
  const trimmed = value.trim();
325
- if (trimmed.length >= 2 && trimmed.startsWith("'") && trimmed.endsWith("'")) {
326
- const inner = trimmed.slice(1, -1);
327
- return inner
328
- .replace(/\\'/g, "'")
329
- .replace(/\\\\/g, "\\")
330
- .replace(/\\n/g, "\n")
331
- .replace(/\\t/g, "\t");
331
+ const quote = trimmed[0];
332
+ if (trimmed.length >= 2 &&
333
+ (quote === "'" || quote === '"') &&
334
+ trimmed.endsWith(quote)) {
335
+ return trimmed
336
+ .slice(1, -1)
337
+ .replace(/\\(.)/gs, (_, char) => PROLOG_ESCAPES[char] ?? char);
332
338
  }
333
339
  return trimmed;
334
340
  }
@@ -3,6 +3,17 @@ import type { PrologStoreLockOwner } from "./error-terms.js";
3
3
  /** Linux boot id; guards against PID reuse across reboots. Null elsewhere. */
4
4
  export declare function currentBootId(): string | null;
5
5
  export declare function isProcessAlive(pid: number): boolean;
6
+ /**
7
+ * The process to stop for a store lock holder. The lock records the engine's
8
+ * SWI-Prolog child; its parent (the daemon, or another Kibi process hosting
9
+ * the session) is what a user ends or stops.
10
+ */
11
+ export declare function lockHolderProcess(pid: number): {
12
+ pid: number;
13
+ prologPid?: number;
14
+ };
15
+ /** "pid N", naming the owning Kibi process when N is its SWI-Prolog child. */
16
+ export declare function describeLockHolderPid(pid: number): string;
6
17
  export type StoreLockHolderState = "self" | "alive" | "dead" | "unknown";
7
18
  export declare function classifyStoreLockHolder(owner: PrologStoreLockOwner | null): StoreLockHolderState;
8
19
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"store-lock.d.ts","sourceRoot":"","sources":["../../src/prolog/store-lock.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,KAAK,EAAqB,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAgBhF,8EAA8E;AAC9E,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAa7C;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAUnD;AAED,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAEzE,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,oBAAoB,GAAG,IAAI,GACjC,oBAAoB,CAYtB;AAED;;;;;GAKG;AAEH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,GAChB;IAAE,KAAK,EAAE,oBAAoB,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA4B7D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAWzD;AAED,qEAAqE;AACrE,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AAEnE;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,QAAsB,CAAC;AAElE,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd,CAAC,CAAC;AAEH;;;GAGG;AAEH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,MAAM,EAAE,MAAM,EACd,EAAE,GAAE,IAAiB,GACpB,IAAI,CAUN;AAED,iFAAiF;AAEjF,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,GAChB,uBAAuB,GAAG,IAAI,CAmBhC;AAED,sEAAsE;AAEtE,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ9D;AAED;;;;;;;;;;;;;;;GAeG;AAEH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,CAerE;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,yEAAyE;AACzE,eAAO,MAAM,gCAAgC,yCACL,CAAC;AAoCzC;;;;;;;;;;;;;;;;;GAiBG;AAEH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,oBAAoB,GAAG,IAAI,EAClC,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,IAAI,CAcf;AAED;;;;;;GAMG;AAEH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,oBAAoB,GAAG,IAAI,EAClC,OAAO,GAAE;IAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5C,yBAAyB,CA+B3B;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;CACxD;AAED;;;;;;GAMG;AAEH,wBAAsB,iCAAiC,CACrD,MAAM,EAAE,qBAAqB,EAC7B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,WAAW,CAAC,CAmCtB"}
1
+ {"version":3,"file":"store-lock.d.ts","sourceRoot":"","sources":["../../src/prolog/store-lock.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,KAAK,EAAqB,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAgBhF,8EAA8E;AAC9E,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAa7C;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAUnD;AA4BD;;;;GAIG;AAEH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAUA;AAED,8EAA8E;AAE9E,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKzD;AAED,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAEzE,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,oBAAoB,GAAG,IAAI,GACjC,oBAAoB,CAYtB;AAED;;;;;GAKG;AAEH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,GAChB;IAAE,KAAK,EAAE,oBAAoB,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA4B7D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAWzD;AAED,qEAAqE;AACrE,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AAEnE;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,QAAsB,CAAC;AAElE,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd,CAAC,CAAC;AAEH;;;GAGG;AAEH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,MAAM,EAAE,MAAM,EACd,EAAE,GAAE,IAAiB,GACpB,IAAI,CAUN;AAED,iFAAiF;AAEjF,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,GAChB,uBAAuB,GAAG,IAAI,CAmBhC;AAED,sEAAsE;AAEtE,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ9D;AAED;;;;;;;;;;;;;;;GAeG;AAEH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,IAAI,CAerE;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,yEAAyE;AACzE,eAAO,MAAM,gCAAgC,yCACL,CAAC;AAoCzC;;;;;;;;;;;;;;;;;GAiBG;AAEH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,oBAAoB,GAAG,IAAI,EAClC,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,IAAI,CAcf;AAED;;;;;;GAMG;AAEH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,oBAAoB,GAAG,IAAI,EAClC,OAAO,GAAE;IAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5C,yBAAyB,CA+B3B;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;CACxD;AAED;;;;;;GAMG;AAEH,wBAAsB,iCAAiC,CACrD,MAAM,EAAE,qBAAqB,EAC7B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,WAAW,CAAC,CAmCtB"}
@@ -15,6 +15,7 @@
15
15
  You should have received a copy of the GNU Affero General Public License
16
16
  along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
  */
18
+ import { execFileSync } from "node:child_process";
18
19
  import { existsSync, realpathSync, rmSync, statSync, writeFileSync, } from "node:fs";
19
20
  import { readFileSync } from "node:fs";
20
21
  import { basename, dirname, join } from "node:path";
@@ -61,6 +62,52 @@ export function isProcessAlive(pid) {
61
62
  return code === "EPERM";
62
63
  }
63
64
  }
65
+ function processInfo(pid) {
66
+ try {
67
+ if (process.platform === "linux") {
68
+ // `comm` is in parentheses; the fields after it are state, ppid, ...
69
+ const stat = readFileSync(`/proc/${pid}/stat`, "utf8");
70
+ const open = stat.indexOf("(");
71
+ const close = stat.lastIndexOf(")");
72
+ return {
73
+ command: stat.slice(open + 1, close),
74
+ parent: Number(stat.slice(close + 2).split(" ")[1]),
75
+ };
76
+ }
77
+ if (process.platform === "win32")
78
+ return null;
79
+ const [parent, ...command] = execFileSync("ps", ["-o", "ppid=,comm=", "-p", String(pid)], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 2000 })
80
+ .trim()
81
+ .split(/\s+/);
82
+ return { parent: Number(parent), command: basename(command.join(" ")) };
83
+ }
84
+ catch {
85
+ return null;
86
+ }
87
+ }
88
+ /**
89
+ * The process to stop for a store lock holder. The lock records the engine's
90
+ * SWI-Prolog child; its parent (the daemon, or another Kibi process hosting
91
+ * the session) is what a user ends or stops.
92
+ */
93
+ // implements REQ-core-journaled-engine-persistence
94
+ export function lockHolderProcess(pid) {
95
+ const info = processInfo(pid);
96
+ if (info === null ||
97
+ !/^swipl/.test(info.command) ||
98
+ !Number.isInteger(info.parent) ||
99
+ info.parent <= 1)
100
+ return { pid };
101
+ return { pid: info.parent, prologPid: pid };
102
+ }
103
+ /** "pid N", naming the owning Kibi process when N is its SWI-Prolog child. */
104
+ // implements REQ-core-journaled-engine-persistence
105
+ export function describeLockHolderPid(pid) {
106
+ const holder = lockHolderProcess(pid);
107
+ return holder.prologPid === undefined
108
+ ? `pid ${holder.pid}`
109
+ : `pid ${holder.pid} (through its SWI-Prolog process, pid ${holder.prologPid})`;
110
+ }
64
111
  export function classifyStoreLockHolder(owner) {
65
112
  if (owner === null || typeof owner.pid !== "number")
66
113
  return "unknown";
@@ -356,7 +403,7 @@ export async function retryAttachAfterBreakingStaleLock(prolog, kbPath, failed)
356
403
  if (decision.action !== "break") {
357
404
  const holderSummary = storeLocked.owner === null
358
405
  ? decision.reason
359
- : `pid ${storeLocked.owner.pid ?? "?"} (${decision.reason})`;
406
+ : `${storeLocked.owner.pid === undefined ? "pid ?" : describeLockHolderPid(storeLocked.owner.pid)} (${decision.reason})`;
360
407
  return {
361
408
  ...failed,
362
409
  error: `${failed.error}