kibi-cli 0.16.1 → 0.18.1

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 (229) hide show
  1. package/dist/cli-json-command.d.ts.map +1 -1
  2. package/dist/cli-json-command.js +87 -11
  3. package/dist/cli-register-maintenance.d.ts.map +1 -1
  4. package/dist/cli-register-maintenance.js +8 -0
  5. package/dist/cli-register-reporting.d.ts.map +1 -1
  6. package/dist/cli-register-reporting.js +5 -0
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/cli.js +2 -1
  9. package/dist/commands/aggregated-checks.d.ts.map +1 -1
  10. package/dist/commands/aggregated-checks.js +1 -0
  11. package/dist/commands/check.d.ts.map +1 -1
  12. package/dist/commands/check.js +1 -1
  13. package/dist/commands/coverage.d.ts +5 -0
  14. package/dist/commands/coverage.d.ts.map +1 -1
  15. package/dist/commands/coverage.js +5 -0
  16. package/dist/commands/discovery-table.d.ts.map +1 -1
  17. package/dist/commands/discovery-table.js +96 -5
  18. package/dist/commands/sync/cache.d.ts +2 -0
  19. package/dist/commands/sync/cache.d.ts.map +1 -1
  20. package/dist/commands/sync/cache.js +8 -0
  21. package/dist/commands/sync/manifest.d.ts +12 -1
  22. package/dist/commands/sync/manifest.d.ts.map +1 -1
  23. package/dist/commands/sync/manifest.js +22 -5
  24. package/dist/commands/sync/persistence.d.ts.map +1 -1
  25. package/dist/commands/sync/persistence.js +76 -2
  26. package/dist/commands/sync.d.ts.map +1 -1
  27. package/dist/commands/sync.js +72 -15
  28. package/dist/commands/usage-metrics.d.ts +66 -2
  29. package/dist/commands/usage-metrics.d.ts.map +1 -1
  30. package/dist/commands/usage-metrics.js +34 -24
  31. package/dist/commands/usage-remediation.d.ts +9 -0
  32. package/dist/commands/usage-remediation.d.ts.map +1 -0
  33. package/dist/commands/usage-remediation.js +52 -0
  34. package/dist/extractors/markdown.d.ts +17 -1
  35. package/dist/extractors/markdown.d.ts.map +1 -1
  36. package/dist/extractors/markdown.js +81 -2
  37. package/dist/logic/ir.d.ts +112 -0
  38. package/dist/logic/ir.d.ts.map +1 -0
  39. package/dist/logic/ir.js +729 -0
  40. package/dist/operations/modeling/logic-modeling.d.ts +22 -0
  41. package/dist/operations/modeling/logic-modeling.d.ts.map +1 -0
  42. package/dist/operations/modeling/logic-modeling.js +120 -0
  43. package/dist/operations/modeling/model-requirement.d.ts.map +1 -1
  44. package/dist/operations/modeling/model-requirement.js +83 -2
  45. package/dist/operations/modeling/predicate-applyplan.d.ts +1 -1
  46. package/dist/operations/modeling/predicate-applyplan.d.ts.map +1 -1
  47. package/dist/operations/modeling/predicate-applyplan.js +29 -4
  48. package/dist/operations/modeling/predicate-inference.d.ts.map +1 -1
  49. package/dist/operations/modeling/predicate-inference.js +3 -0
  50. package/dist/operations/modeling/predicate-loader.d.ts.map +1 -1
  51. package/dist/operations/modeling/predicate-loader.js +7 -1
  52. package/dist/operations/modeling/predicate-ranker.d.ts.map +1 -1
  53. package/dist/operations/modeling/predicate-ranker.js +40 -2
  54. package/dist/operations/modeling/predicate-types.d.ts +12 -1
  55. package/dist/operations/modeling/predicate-types.d.ts.map +1 -1
  56. package/dist/operations/modeling/requirement-types.d.ts +12 -0
  57. package/dist/operations/modeling/requirement-types.d.ts.map +1 -1
  58. package/dist/operations/modeling/suggest-predicates.d.ts.map +1 -1
  59. package/dist/operations/modeling/suggest-predicates.js +35 -11
  60. package/dist/operations/mutation/audit.js +1 -1
  61. package/dist/operations/mutation/contradictions.d.ts +1 -1
  62. package/dist/operations/mutation/contradictions.d.ts.map +1 -1
  63. package/dist/operations/mutation/contradictions.js +23 -18
  64. package/dist/operations/mutation/relationships.d.ts.map +1 -1
  65. package/dist/operations/mutation/relationships.js +8 -0
  66. package/dist/operations/mutation/serialization.d.ts.map +1 -1
  67. package/dist/operations/mutation/serialization.js +6 -0
  68. package/dist/operations/mutation/strict-fact.d.ts.map +1 -1
  69. package/dist/operations/mutation/strict-fact.js +68 -3
  70. package/dist/operations/mutation/upsert.d.ts +3 -1
  71. package/dist/operations/mutation/upsert.d.ts.map +1 -1
  72. package/dist/operations/mutation/upsert.js +51 -12
  73. package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
  74. package/dist/operations/mutation/validate-upsert.js +18 -2
  75. package/dist/operations/mutation/validation.d.ts.map +1 -1
  76. package/dist/operations/mutation/validation.js +8 -0
  77. package/dist/operations/semantic-advisor/analysis-receipt.d.ts +2 -2
  78. package/dist/operations/semantic-advisor/analysis-receipt.d.ts.map +1 -1
  79. package/dist/operations/semantic-advisor/analysis-receipt.js +30 -16
  80. package/dist/operations/semantic-advisor/analyze-prose.d.ts +1 -1
  81. package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
  82. package/dist/operations/semantic-advisor/analyze-prose.js +464 -27
  83. package/dist/operations/semantic-advisor/clauses.d.ts +1 -0
  84. package/dist/operations/semantic-advisor/clauses.d.ts.map +1 -1
  85. package/dist/operations/semantic-advisor/clauses.js +7 -7
  86. package/dist/operations/semantic-advisor/ingestion-boundary.d.ts +18 -0
  87. package/dist/operations/semantic-advisor/ingestion-boundary.d.ts.map +1 -0
  88. package/dist/operations/semantic-advisor/ingestion-boundary.js +167 -0
  89. package/dist/operations/semantic-advisor/observation-plan.d.ts.map +1 -1
  90. package/dist/operations/semantic-advisor/observation-plan.js +15 -3
  91. package/dist/operations/semantic-advisor/shared.d.ts +9 -0
  92. package/dist/operations/semantic-advisor/shared.d.ts.map +1 -1
  93. package/dist/operations/semantic-advisor/shared.js +38 -4
  94. package/dist/operations/semantic-advisor/types.d.ts +66 -1
  95. package/dist/operations/semantic-advisor/types.d.ts.map +1 -1
  96. package/dist/prolog/codec.d.ts.map +1 -1
  97. package/dist/prolog/codec.js +19 -2
  98. package/dist/prolog.d.ts +6 -0
  99. package/dist/prolog.d.ts.map +1 -1
  100. package/dist/prolog.js +247 -63
  101. package/dist/public/diagnostic-usage.d.ts +17 -0
  102. package/dist/public/diagnostic-usage.d.ts.map +1 -0
  103. package/dist/public/diagnostic-usage.js +152 -0
  104. package/dist/public/distribution-parity.d.ts +90 -0
  105. package/dist/public/distribution-parity.d.ts.map +1 -0
  106. package/dist/public/distribution-parity.js +367 -0
  107. package/dist/public/impact/full-kb-quality.d.ts +2 -0
  108. package/dist/public/impact/full-kb-quality.d.ts.map +1 -1
  109. package/dist/public/impact/full-kb-quality.js +53 -1
  110. package/dist/public/impact-diagnostics.d.ts +2 -0
  111. package/dist/public/impact-diagnostics.d.ts.map +1 -1
  112. package/dist/public/impact-diagnostics.js +1 -0
  113. package/dist/public/operations/catalog.d.ts +235 -11
  114. package/dist/public/operations/catalog.d.ts.map +1 -1
  115. package/dist/public/operations/check-executor.d.ts.map +1 -1
  116. package/dist/public/operations/check-executor.js +4 -0
  117. package/dist/public/operations/discovery-executors.d.ts +6 -0
  118. package/dist/public/operations/discovery-executors.d.ts.map +1 -1
  119. package/dist/public/operations/discovery-executors.js +18 -2
  120. package/dist/public/operations/index.d.ts +5 -0
  121. package/dist/public/operations/index.d.ts.map +1 -1
  122. package/dist/public/operations/index.js +5 -0
  123. package/dist/public/operations/legacy-migration-plan.d.ts +113 -0
  124. package/dist/public/operations/legacy-migration-plan.d.ts.map +1 -0
  125. package/dist/public/operations/legacy-migration-plan.js +409 -0
  126. package/dist/public/operations/node-ports.d.ts.map +1 -1
  127. package/dist/public/operations/node-ports.js +90 -0
  128. package/dist/public/operations/repair-plan.d.ts +184 -0
  129. package/dist/public/operations/repair-plan.d.ts.map +1 -0
  130. package/dist/public/operations/repair-plan.js +397 -0
  131. package/dist/public/operations/runtime-types.d.ts +7 -0
  132. package/dist/public/operations/runtime-types.d.ts.map +1 -1
  133. package/dist/public/operations/specs/check.d.ts +3 -3
  134. package/dist/public/operations/specs/check.d.ts.map +1 -1
  135. package/dist/public/operations/specs/check.js +5 -2
  136. package/dist/public/operations/specs/discovery.d.ts +1 -1
  137. package/dist/public/operations/specs/discovery.js +1 -1
  138. package/dist/public/operations/specs/modeling.d.ts +35 -1
  139. package/dist/public/operations/specs/modeling.d.ts.map +1 -1
  140. package/dist/public/operations/specs/modeling.js +32 -1
  141. package/dist/public/operations/specs/mutation-schemas.d.ts +133 -3
  142. package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
  143. package/dist/public/operations/specs/mutation-schemas.js +67 -1
  144. package/dist/public/operations/specs/reporting.d.ts +42 -1
  145. package/dist/public/operations/specs/reporting.d.ts.map +1 -1
  146. package/dist/public/operations/specs/reporting.js +70 -6
  147. package/dist/public/operations/specs/semantic.d.ts +30 -2
  148. package/dist/public/operations/specs/semantic.d.ts.map +1 -1
  149. package/dist/public/operations/specs/semantic.js +35 -3
  150. package/dist/public/operations/specs/upsert.d.ts +133 -3
  151. package/dist/public/operations/specs/upsert.d.ts.map +1 -1
  152. package/dist/public/operations/workspace-snapshot.d.ts +10 -0
  153. package/dist/public/operations/workspace-snapshot.d.ts.map +1 -0
  154. package/dist/public/operations/workspace-snapshot.js +20 -0
  155. package/dist/public/schemas/entity.d.ts.map +1 -1
  156. package/dist/public/schemas/entity.js +332 -0
  157. package/dist/public/schemas/relationship.d.ts.map +1 -1
  158. package/dist/public/schemas/relationship.js +1 -0
  159. package/dist/public/skills/kibi-traceability/SKILL.md +7 -1
  160. package/dist/public/skills/kibi-usage/SKILL.md +44 -12
  161. package/dist/public/skills/kibi-usage/resources/fact-lanes.md +12 -2
  162. package/dist/public/skills/kibi-usage/resources/logic-ir.md +43 -0
  163. package/dist/public/skills/kibi-usage/resources/operation-access.md +19 -19
  164. package/dist/public/skills/kibi-usage/resources/ui-requirements.md +96 -0
  165. package/dist/public/skills/kibi-usage/resources/workflows.md +40 -8
  166. package/dist/public/symbol-granularity.d.ts +9 -0
  167. package/dist/public/symbol-granularity.d.ts.map +1 -1
  168. package/dist/public/symbol-granularity.js +16 -0
  169. package/dist/public/telemetry-acceptance.d.ts +89 -0
  170. package/dist/public/telemetry-acceptance.d.ts.map +1 -0
  171. package/dist/public/telemetry-acceptance.js +597 -0
  172. package/dist/public/telemetry-remediation.d.ts +33 -0
  173. package/dist/public/telemetry-remediation.d.ts.map +1 -0
  174. package/dist/public/telemetry-remediation.js +257 -0
  175. package/dist/public/verification-receipt.d.ts +75 -0
  176. package/dist/public/verification-receipt.d.ts.map +1 -0
  177. package/dist/public/verification-receipt.js +129 -0
  178. package/dist/schemas/entity.schema.json +401 -4
  179. package/dist/traceability/staged-diagnostics.d.ts +1 -1
  180. package/dist/traceability/staged-diagnostics.d.ts.map +1 -1
  181. package/dist/traceability/staged-diagnostics.js +17 -10
  182. package/dist/traceability/staged-impact-contract.js +1 -1
  183. package/dist/traceability/staged-symbols-manifest.d.ts.map +1 -1
  184. package/dist/traceability/staged-symbols-manifest.js +28 -10
  185. package/dist/traceability/temp-kb.d.ts.map +1 -1
  186. package/dist/traceability/temp-kb.js +49 -3
  187. package/dist/types/entities.d.ts +1 -0
  188. package/dist/types/entities.d.ts.map +1 -1
  189. package/dist/types/relationships.d.ts +1 -1
  190. package/dist/types/relationships.d.ts.map +1 -1
  191. package/dist/utils/rule-registry.d.ts +2 -0
  192. package/dist/utils/rule-registry.d.ts.map +1 -1
  193. package/dist/utils/rule-registry.js +18 -0
  194. package/dist/utils/schema-version.d.ts +1 -1
  195. package/dist/utils/schema-version.js +1 -1
  196. package/package.json +34 -2
  197. package/src/public/diagnostic-usage.ts +206 -0
  198. package/src/public/distribution-parity.ts +580 -0
  199. package/src/public/impact/full-kb-quality.ts +74 -1
  200. package/src/public/impact-diagnostics.ts +16 -0
  201. package/src/public/operations/check-executor.ts +4 -0
  202. package/src/public/operations/discovery-executors.ts +24 -2
  203. package/src/public/operations/index.ts +5 -0
  204. package/src/public/operations/legacy-migration-plan.ts +688 -0
  205. package/src/public/operations/node-ports.ts +109 -0
  206. package/src/public/operations/repair-plan.ts +562 -0
  207. package/src/public/operations/runtime-types.ts +8 -0
  208. package/src/public/operations/specs/check.ts +5 -2
  209. package/src/public/operations/specs/discovery.ts +1 -1
  210. package/src/public/operations/specs/modeling.ts +39 -1
  211. package/src/public/operations/specs/mutation-schemas.ts +77 -1
  212. package/src/public/operations/specs/reporting.ts +91 -6
  213. package/src/public/operations/specs/semantic.ts +42 -3
  214. package/src/public/operations/workspace-snapshot.ts +28 -0
  215. package/src/public/schemas/entity.ts +340 -1
  216. package/src/public/schemas/relationship.ts +1 -0
  217. package/src/public/skills/kibi-traceability/SKILL.md +7 -1
  218. package/src/public/skills/kibi-usage/SKILL.md +44 -12
  219. package/src/public/skills/kibi-usage/resources/fact-lanes.md +12 -2
  220. package/src/public/skills/kibi-usage/resources/logic-ir.md +43 -0
  221. package/src/public/skills/kibi-usage/resources/operation-access.md +19 -19
  222. package/src/public/skills/kibi-usage/resources/ui-requirements.md +96 -0
  223. package/src/public/skills/kibi-usage/resources/workflows.md +40 -8
  224. package/src/public/symbol-granularity.ts +25 -0
  225. package/src/public/telemetry-acceptance.ts +859 -0
  226. package/src/public/telemetry-remediation.ts +462 -0
  227. package/src/public/verification-receipt.ts +170 -0
  228. package/src/schemas/entity.schema.json +401 -4
  229. package/src/schemas/relationship.schema.json +1 -0
@@ -4,7 +4,7 @@ type TransactionInput = {
4
4
  readonly relationships: readonly RelationshipInput[];
5
5
  readonly skipContradictionCheck: boolean;
6
6
  };
7
- export declare function buildUpsertTransaction(input: TransactionInput): string;
7
+ export declare function buildUpsertCommitGoal(input: TransactionInput): string;
8
8
  export declare function formatUpsertError(entityId: string, raw?: string): string;
9
9
  export {};
10
10
  //# sourceMappingURL=contradictions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"contradictions.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/contradictions.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,KAAK,gBAAgB,GAAG;IACtB,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;CAC1C,CAAC;AAGF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CActE;AAGD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CA0BxE"}
1
+ {"version":3,"file":"contradictions.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/contradictions.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,KAAK,gBAAgB,GAAG;IACtB,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;CAC1C,CAAC;AAGF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAOrE;AAGD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CA6CxE"}
@@ -2,39 +2,44 @@ import { escapeAtom } from "../../prolog/codec.js";
2
2
  import { formatInvalidRelationshipError } from "./relationships.js";
3
3
  import { buildPropertyList, buildRelationshipMetadata, } from "./serialization.js";
4
4
  // implements REQ-kibi-operation-interface-parity
5
- export function buildUpsertTransaction(input) {
6
- const id = String(input.entity.id);
5
+ export function buildUpsertCommitGoal(input) {
7
6
  const type = String(input.entity.type);
8
- const goals = [
9
- `kb_assert_entity_no_audit(${type}, ${buildPropertyList(input.entity)})`,
10
- ...input.relationships.map((relationship) => `kb_assert_relationship_no_audit(${String(relationship.type)}, '${escapeAtom(String(relationship.from))}', '${escapeAtom(String(relationship.to))}', ${buildRelationshipMetadata(relationship)})`),
11
- ];
12
- if (type === "req" && !input.skipContradictionCheck) {
13
- goals.push(`check_req_contradiction('${escapeAtom(id)}')`);
14
- }
15
- return `rdf_transaction((${goals.join(", ")}))`;
7
+ const relationships = input.relationships.map((relationship) => `rel(${String(relationship.type)}, '${escapeAtom(String(relationship.from))}', '${escapeAtom(String(relationship.to))}', ${buildRelationshipMetadata(relationship)})`);
8
+ return `kb_commit_upsert(${type}, ${buildPropertyList(input.entity)}, [${relationships.join(", ")}], ${input.skipContradictionCheck ? "true" : "false"}, ChangeKind)`;
16
9
  }
17
10
  // implements REQ-kibi-operation-interface-parity
18
11
  export function formatUpsertError(entityId, raw) {
19
12
  if (!raw)
20
13
  return `Failed to upsert entity ${entityId}: Unknown error`;
21
- const invalidRelationship = formatInvalidRelationshipError(raw);
14
+ const stage = raw.match(/\(stage=([^)]+)\)/)?.[1];
15
+ const stageSuffix = stage === undefined ? "" : ` (stage=${stage})`;
16
+ const diagnosticFree = raw.replace(/^__KIBI_(?:STAGE|RUNTIME)__:[^\r\n]*\r?\n?/gm, "");
17
+ if (diagnosticFree.includes("stale_snapshot")) {
18
+ return `Failed to upsert entity ${entityId}: KB snapshot is stale; reattach or refresh the runtime before retrying (stale_snapshot)${stageSuffix}`;
19
+ }
20
+ if (diagnosticFree.includes("Audit journal is locked") ||
21
+ diagnosticFree.includes("audit_log") ||
22
+ diagnosticFree.includes("audit.log") ||
23
+ diagnosticFree.includes("Resource temporarily unavailable")) {
24
+ return `Failed to upsert entity ${entityId}: Audit journal is locked by another Kibi runtime; restart the stale MCP/CLI session before retrying${stageSuffix}`;
25
+ }
26
+ const invalidRelationship = formatInvalidRelationshipError(diagnosticFree);
22
27
  if (invalidRelationship !== null) {
23
- return `Failed to upsert entity ${entityId}: ${invalidRelationship}`;
28
+ return `Failed to upsert entity ${entityId}: ${invalidRelationship}${stageSuffix}`;
24
29
  }
25
- const contradiction = raw.match(/kb_contradiction\(\s*\[([^\]]+)\]\s*\)/);
30
+ const contradiction = diagnosticFree.match(/kb_contradiction\(\s*\[([^\]]+)\]\s*\)/);
26
31
  if (contradiction) {
27
32
  const details = contradiction[1] ?? "";
28
33
  const conflicts = [
29
34
  ...details.matchAll(/(?:'([^']+)'|"([^"\\]*(?:\\.[^"\\]*)*)")-'([^']+)'/g),
30
35
  ].map((match) => ` - Conflicts with ${String(match[3])}: ${String(match[1] ?? match[2])}`);
31
36
  if (conflicts.length > 0) {
32
- return `Contradiction detected for requirement ${entityId}:\n${[...new Set(conflicts)].join("\n")}\n\nTo resolve:\n 1. Add a supersedes relationship from the new requirement to the conflicting one, OR\n 2. Deprecate the conflicting requirement before creating the new one.`;
37
+ return `Contradiction detected for requirement ${entityId}:\n${[...new Set(conflicts)].join("\n")}\n\nTo resolve:\n 1. Add a supersedes relationship from the new requirement to the conflicting one, OR\n 2. Deprecate the conflicting requirement before creating the new one.${stageSuffix}`;
33
38
  }
34
- return `Contradiction detected for entity ${entityId}: This requirement conflicts with existing requirements. Add a supersedes relationship to the conflicting requirement, or deprecate the old requirement before creating the new one.`;
39
+ return `Contradiction detected for entity ${entityId}: This requirement conflicts with existing requirements. Add a supersedes relationship to the conflicting requirement, or deprecate the old requirement before creating the new one.${stageSuffix}`;
35
40
  }
36
- if (raw.includes("rdf_transaction")) {
37
- return `Failed to upsert entity ${entityId}: Transaction failed`;
41
+ if (diagnosticFree.includes("rdf_transaction")) {
42
+ return `Failed to upsert entity ${entityId}: Transaction failed${stageSuffix}`;
38
43
  }
39
- return `Failed to upsert entity ${entityId}: ${raw}`;
44
+ return `Failed to upsert entity ${entityId}: ${diagnosticFree || raw}`;
40
45
  }
@@ -1 +1 @@
1
- {"version":3,"file":"relationships.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/relationships.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAE3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAqBpD,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,KAAK,iBAAiB,GAAG;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAgCF,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,iBAAiB,GACvB,MAAM,CAER;AAED,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAczE;AAED,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,SAAS,iBAAiB,EAAE,GAC1C,IAAI,CAMN;AAED,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,iBAAiB,GAC9B,MAAM,CAIR;AAuBD,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,aAAa,EAAE,SAAS,iBAAiB,EAAE,GAC1C,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,UAAU,EAClB,aAAa,EAAE,SAAS,iBAAiB,EAAE,GAC1C,OAAO,CAAC,IAAI,CAAC,CAqBf;AAED,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC,CAevC"}
1
+ {"version":3,"file":"relationships.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/relationships.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAE3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAsBpD,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEnE;AAED,KAAK,iBAAiB,GAAG;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB,CAAC;AAgCF,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,iBAAiB,GACvB,MAAM,CAER;AAED,wBAAgB,8BAA8B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAczE;AAED,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,SAAS,iBAAiB,EAAE,GAC1C,IAAI,CAMN;AAED,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,iBAAiB,GAC9B,MAAM,CAIR;AAuBD,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,aAAa,EAAE,SAAS,iBAAiB,EAAE,GAC1C,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,UAAU,EAClB,aAAa,EAAE,SAAS,iBAAiB,EAAE,GAC1C,OAAO,CAAC,IAAI,CAAC,CAgCf;AAED,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC,CAevC"}
@@ -12,6 +12,7 @@ const RELATIONSHIP_TYPES = [
12
12
  "constrains",
13
13
  "requires_property",
14
14
  "requires_predicate",
15
+ "requires_rule",
15
16
  "guards",
16
17
  "publishes",
17
18
  "consumes",
@@ -106,6 +107,13 @@ export async function validateLiveRelationshipTargets(prolog, entity, relationsh
106
107
  export async function validateStrictLanePairing(prolog, relationships) {
107
108
  for (const relationship of relationships) {
108
109
  const target = stringField(relationship, "to");
110
+ if (relationship.type === "requires_rule") {
111
+ const result = await prolog.query(`once((kb_entity('${escapeAtom(target)}', fact, _RuleProps), memberchk(fact_kind=_RuleKind, _RuleProps), normalize_term_atom(_RuleKind, rule)))`);
112
+ if (!result.success) {
113
+ throw new Error(`Relationship 'requires_rule' requires target '${target}' to be a fact_kind=rule fact.`);
114
+ }
115
+ continue;
116
+ }
109
117
  const wrongKind = relationship.type === "constrains"
110
118
  ? "property_value"
111
119
  : relationship.type === "requires_property"
@@ -1 +1 @@
1
- {"version":3,"file":"serialization.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/serialization.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AA0CpD,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC,MAAM,CAMR;AAGD,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,iBAAiB,GAAG,MAAM,CAOxE;AAGD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAkBtD"}
1
+ {"version":3,"file":"serialization.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/serialization.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAkDpD,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC,MAAM,CAMR;AAGD,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,iBAAiB,GAAG,MAAM,CAOxE;AAGD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAkBtD"}
@@ -20,11 +20,17 @@ const STRING_FIELDS = [
20
20
  "updated_at",
21
21
  "source",
22
22
  "text_ref",
23
+ "semantic_text",
23
24
  ];
24
25
  function serializeValue(key, value) {
25
26
  if (key === "id" && typeof value === "string") {
26
27
  return `'${value.replaceAll("'", "''")}'`;
27
28
  }
29
+ if (key === "rule_ir" ||
30
+ key === "semantic_inventory" ||
31
+ key === "verification_receipts") {
32
+ return toPrologString(JSON.stringify(value));
33
+ }
28
34
  if (Array.isArray(value))
29
35
  return JSON.stringify(value);
30
36
  if (typeof value === "string") {
@@ -1 +1 @@
1
- {"version":3,"file":"strict-fact.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/strict-fact.ts"],"names":[],"mappings":"AAQA,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAarD;AAGD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC,MAAM,EAAE,CAyCV;AAGD,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC,IAAI,CAKN"}
1
+ {"version":3,"file":"strict-fact.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/strict-fact.ts"],"names":[],"mappings":"AAUA,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAarD;AAGD,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC,MAAM,EAAE,CA+EV;AAGD,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACxC,IAAI,CAuDN"}
@@ -1,3 +1,4 @@
1
+ import { validateLogicIr } from "../../logic/ir.js";
1
2
  const PROPERTY_VALUE_FIELDS = [
2
3
  "value_string",
3
4
  "value_int",
@@ -43,6 +44,40 @@ export function factKindShapeHints(entity) {
43
44
  }
44
45
  return hints;
45
46
  }
47
+ if (entity.fact_kind === "rule_schema") {
48
+ const missing = ["rule_name", "argument_names", "argument_types"].filter((field) => entity[field] === undefined);
49
+ const equalLengths = Array.isArray(entity.argument_names) &&
50
+ Array.isArray(entity.argument_types) &&
51
+ entity.argument_names.length === entity.argument_types.length;
52
+ const hints = missing.length > 0
53
+ ? [`fact_kind 'rule_schema' requires ${missing.join(", ")}.`]
54
+ : equalLengths
55
+ ? []
56
+ : [
57
+ "fact_kind 'rule_schema' requires argument_names and argument_types with equal lengths.",
58
+ ];
59
+ return hints.length > 0
60
+ ? [
61
+ ...hints,
62
+ "Next action: define the kibi.logic.v1 schema before creating rule facts.",
63
+ ]
64
+ : [];
65
+ }
66
+ if (entity.fact_kind === "rule") {
67
+ const missing = [
68
+ "rule_ir",
69
+ "rule_hash",
70
+ "rule_schema_id",
71
+ "rule_name",
72
+ "semantic_key",
73
+ ].filter((field) => entity[field] === undefined);
74
+ return missing.length > 0
75
+ ? [
76
+ `fact_kind 'rule' requires ${missing.join(", ")}.`,
77
+ "Next action: call kb_model_requirement with typed kibi.logic.v1 IR; raw Prolog is not accepted.",
78
+ ]
79
+ : [];
80
+ }
46
81
  if (entity.fact_kind !== "predicate")
47
82
  return [];
48
83
  const args = entity.predicate_args;
@@ -51,12 +86,12 @@ export function factKindShapeHints(entity) {
51
86
  ...(!Array.isArray(args) || args.length === 0 ? ["predicate_args"] : []),
52
87
  ...(entity.canonical_key === undefined ? ["canonical_key"] : []),
53
88
  ];
54
- return missing.length === 0
55
- ? []
56
- : [
89
+ if (missing.length !== 0)
90
+ return [
57
91
  `fact_kind 'predicate' requires ${missing.join(", ")}.`,
58
92
  "Next action: call kb_suggest_predicates before hand-writing ontology predicate facts.",
59
93
  ];
94
+ return [];
60
95
  }
61
96
  // implements REQ-kibi-operation-interface-parity
62
97
  export function validateFactModelingShape(entity) {
@@ -64,4 +99,34 @@ export function validateFactModelingShape(entity) {
64
99
  if (hints.length > 0) {
65
100
  throw new Error(`Entity validation failed: ${hints.join("; ")}`);
66
101
  }
102
+ if (entity.type === "fact" && entity.fact_kind === "rule") {
103
+ const validation = validateLogicIr(entity.rule_ir);
104
+ if (!validation.valid || !validation.semanticKey) {
105
+ throw new Error(`Entity validation failed: rule_ir is unsafe or malformed (${validation.errors.join("; ")})`);
106
+ }
107
+ if (entity.rule_hash !== undefined &&
108
+ entity.rule_hash !== validation.ruleHash) {
109
+ throw new Error(`Entity validation failed: rule_hash must equal ${validation.ruleHash}`);
110
+ }
111
+ if (entity.semantic_key !== undefined &&
112
+ entity.semantic_key !== validation.semanticKey) {
113
+ throw new Error(`Entity validation failed: semantic_key must equal ${validation.semanticKey}`);
114
+ }
115
+ for (const field of ["rule_schema_id", "rule_name"]) {
116
+ if (typeof entity[field] !== "string" || entity[field].trim() === "") {
117
+ throw new Error(`Entity validation failed: fact_kind 'rule' requires ${field}`);
118
+ }
119
+ }
120
+ }
121
+ if (entity.type === "fact" && entity.fact_kind === "rule_schema") {
122
+ if (typeof entity.rule_name !== "string" ||
123
+ entity.rule_name.trim() === "") {
124
+ throw new Error("Entity validation failed: fact_kind 'rule_schema' requires rule_name");
125
+ }
126
+ if (!Array.isArray(entity.argument_names) ||
127
+ !Array.isArray(entity.argument_types) ||
128
+ entity.argument_names.length !== entity.argument_types.length) {
129
+ throw new Error("Entity validation failed: rule_schema argument_names and argument_types must have equal lengths");
130
+ }
131
+ }
67
132
  }
@@ -1,5 +1,7 @@
1
1
  import type { OperationContext } from "../../public/operations/runtime-types.js";
2
2
  import type { OperationResult } from "../../public/operations/types.js";
3
- import type { UpsertInput, UpsertPayload } from "./types.js";
3
+ import type { RelationshipInput, UpsertInput, UpsertPayload } from "./types.js";
4
+ export declare function validateAppendOnlyVerificationReceipts(entity: Readonly<Record<string, unknown>>, context: OperationContext): Promise<void>;
5
+ export declare function effectiveRelationships(input: UpsertInput, entity: Readonly<Record<string, unknown>>, relationships: readonly RelationshipInput[], context: OperationContext): Promise<readonly RelationshipInput[]>;
4
6
  export declare function executeUpsert(input: UpsertInput, context: OperationContext): Promise<OperationResult<UpsertPayload>>;
5
7
  //# sourceMappingURL=upsert.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"upsert.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/upsert.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AACjF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAaxE,OAAO,KAAK,EAAqB,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAkChF,wBAAsB,aAAa,CACjC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CA0FzC"}
1
+ {"version":3,"file":"upsert.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/upsert.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AACjF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAgBxE,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AA8BhF,wBAAsB,sCAAsC,CAC1D,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,aAAa,EAAE,SAAS,iBAAiB,EAAE,EAC3C,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC,CAgBvC;AAED,wBAAsB,aAAa,CACjC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CAuGzC"}
@@ -1,9 +1,10 @@
1
1
  import { escapeAtom } from "../../prolog/codec.js";
2
+ import { loadEntities } from "../../public/operations/discovery-entities.js";
3
+ import { appendOnlyVerificationReceiptHistoryErrors } from "../../public/verification-receipt.js";
2
4
  import { analyzeSemanticAdvisorInput } from "../semantic-advisor/analyze-prose.js";
3
- import { recordEntityAudit, recordRelationshipAudits } from "./audit.js";
4
- import { buildUpsertTransaction, formatUpsertError } from "./contradictions.js";
5
+ import { assertLogicalGroundingClaimKeys, assertSemanticInventoryBoundary, } from "../semantic-advisor/ingestion-boundary.js";
6
+ import { buildUpsertCommitGoal, formatUpsertError } from "./contradictions.js";
5
7
  import { existingRelationships, validateLiveRelationshipTargets, validateRelationshipSources, validateStrictLanePairing, } from "./relationships.js";
6
- import { saveMutation } from "./save.js";
7
8
  import { validateSymbolGranularity } from "./symbol-granularity.js";
8
9
  import { refreshSymbolCoordinates } from "./symbol-refresh.js";
9
10
  import { validateUpsertInput } from "./validation.js";
@@ -14,7 +15,36 @@ function requireProlog(context) {
14
15
  }
15
16
  return context.prolog;
16
17
  }
17
- async function effectiveRelationships(input, entity, relationships, context) {
18
+ function receiptRecords(value) {
19
+ if (!Array.isArray(value))
20
+ return undefined;
21
+ return value.filter((receipt) => receipt !== null &&
22
+ typeof receipt === "object" &&
23
+ !Array.isArray(receipt));
24
+ }
25
+ function parseChangeKind(value) {
26
+ const normalized = value?.trim().replace(/^['"]|['"]$/g, "");
27
+ return normalized === "created" || normalized === "updated"
28
+ ? normalized
29
+ : null;
30
+ }
31
+ export async function validateAppendOnlyVerificationReceipts(entity, context) {
32
+ if (entity.type !== "test")
33
+ return;
34
+ const existing = await loadEntities(requireProlog(context), {
35
+ id: String(entity.id),
36
+ type: "test",
37
+ });
38
+ const previous = receiptRecords(existing[0]?.verification_receipts);
39
+ if (!previous || previous.length === 0)
40
+ return;
41
+ const next = receiptRecords(entity.verification_receipts);
42
+ const errors = appendOnlyVerificationReceiptHistoryErrors(previous, next);
43
+ if (errors.length > 0) {
44
+ throw new Error(`Entity validation failed: ${errors.join("; ")}`);
45
+ }
46
+ }
47
+ export async function effectiveRelationships(input, entity, relationships, context) {
18
48
  if (input.relationships !== undefined && input.relationships.length > 0) {
19
49
  return relationships;
20
50
  }
@@ -36,13 +66,18 @@ export async function executeUpsert(input, context) {
36
66
  const prolog = requireProlog(context);
37
67
  try {
38
68
  const validated = validateUpsertInput(input, context.clock());
69
+ await validateAppendOnlyVerificationReceipts(validated.entity, context);
39
70
  validateRelationshipSources(input.id, validated.relationships);
40
71
  await validateSymbolGranularity(validated.entity, validated.relationships, context);
41
72
  const relationships = await effectiveRelationships(input, validated.entity, validated.relationships, context);
42
73
  await validateStrictLanePairing(prolog, relationships);
43
74
  await validateLiveRelationshipTargets(prolog, validated.entity, relationships);
44
- const exists = await prolog.query(`once(kb_entity('${escapeAtom(input.id)}', _, _))`);
45
- const transaction = buildUpsertTransaction({
75
+ const semantic = analyzeSemanticAdvisorInput({
76
+ payload: { ...input, relationships },
77
+ });
78
+ assertSemanticInventoryBoundary({ ...input, relationships }, relationships, semantic.receipt);
79
+ await assertLogicalGroundingClaimKeys(prolog, { ...input, relationships }, relationships);
80
+ const transaction = buildUpsertCommitGoal({
46
81
  entity: validated.entity,
47
82
  relationships,
48
83
  skipContradictionCheck: input._skipContradictionCheck === true,
@@ -51,9 +86,14 @@ export async function executeUpsert(input, context) {
51
86
  if (!written.success) {
52
87
  throw new Error(formatUpsertError(input.id, written.error));
53
88
  }
54
- await recordEntityAudit(prolog, exists.success ? "updated" : "created", validated.entity);
55
- await recordRelationshipAudits(prolog, relationships);
56
- await saveMutation(prolog);
89
+ // The combined commit is the sole mutation boundary. Invalidate reads only
90
+ // after Prolog reports success so a failed/rolled-back commit does not
91
+ // disturb callers' view of the current snapshot.
92
+ prolog.invalidateCache?.();
93
+ const changeKind = parseChangeKind(written.bindings.ChangeKind);
94
+ if (changeKind === null) {
95
+ throw new Error(`Upsert commit completed without a created/updated result for ${input.id}`);
96
+ }
57
97
  if (input.type === "symbol") {
58
98
  try {
59
99
  await refreshSymbolCoordinates(input.id, context);
@@ -63,12 +103,11 @@ export async function executeUpsert(input, context) {
63
103
  throw error;
64
104
  }
65
105
  }
66
- const semantic = analyzeSemanticAdvisorInput({ payload: { ...input } });
67
106
  const coverage = await scenarioCoverageWarnings(prolog, validated.relationships, input.type, input.id);
68
- const created = exists.success ? 0 : 1;
107
+ const created = changeKind === "created" ? 1 : 0;
69
108
  const payload = {
70
109
  created,
71
- updated: exists.success ? 1 : 0,
110
+ updated: changeKind === "updated" ? 1 : 0,
72
111
  relationships_created: relationships.length,
73
112
  warnings: [...semantic.warnings, ...coverage],
74
113
  semanticAdvisor: semantic.receipt,
@@ -1 +1 @@
1
- {"version":3,"file":"validate-upsert.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/validate-upsert.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AACjF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAOxE,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAGrE,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,qBAAqB,CAAC,CAAC,CAoDjD"}
1
+ {"version":3,"file":"validate-upsert.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/validate-upsert.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AACjF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAYxE,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAOrE,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,qBAAqB,CAAC,CAAC,CAoFjD"}
@@ -1,16 +1,32 @@
1
1
  import { analyzeSemanticAdvisorInput } from "../semantic-advisor/analyze-prose.js";
2
+ import { assertLogicalGroundingClaimKeys, assertSemanticInventoryBoundary, validateSemanticInventoryBoundary, } from "../semantic-advisor/ingestion-boundary.js";
2
3
  import { validateLiveRelationshipTargets, validateRelationshipSources, } from "./relationships.js";
3
4
  import { validateSymbolGranularity } from "./symbol-granularity.js";
5
+ import { effectiveRelationships, validateAppendOnlyVerificationReceipts, } from "./upsert.js";
4
6
  import { validateUpsertInput } from "./validation.js";
5
7
  export async function executeValidateUpsert(input, context) {
6
8
  try {
7
9
  const validated = validateUpsertInput(input, context.clock());
10
+ await validateAppendOnlyVerificationReceipts(validated.entity, context);
8
11
  validateRelationshipSources(input.id, validated.relationships);
9
12
  await validateSymbolGranularity(validated.entity, validated.relationships, context);
13
+ const previewSemantic = analyzeSemanticAdvisorInput({
14
+ payload: { ...input, relationships: validated.relationships },
15
+ });
16
+ const previewBoundary = validateSemanticInventoryBoundary({ ...input, relationships: validated.relationships }, validated.relationships, previewSemantic.receipt);
17
+ const relationships = context.prolog === undefined || !previewBoundary.applicable
18
+ ? validated.relationships
19
+ : await effectiveRelationships(input, validated.entity, validated.relationships, context);
10
20
  if (context.prolog !== undefined) {
11
- await validateLiveRelationshipTargets(context.prolog, validated.entity, validated.relationships);
21
+ await validateLiveRelationshipTargets(context.prolog, validated.entity, relationships);
22
+ }
23
+ const semantic = analyzeSemanticAdvisorInput({
24
+ payload: { ...input, relationships },
25
+ });
26
+ assertSemanticInventoryBoundary({ ...input, relationships }, relationships, semantic.receipt);
27
+ if (context.prolog !== undefined) {
28
+ await assertLogicalGroundingClaimKeys(context.prolog, { ...input, relationships }, relationships);
12
29
  }
13
- const semantic = analyzeSemanticAdvisorInput({ payload: { ...input } });
14
30
  const payload = {
15
31
  valid: true,
16
32
  errors: [],
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/validation.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,0BAA0B,EAC3B,MAAM,oCAAoC,CAAC;AAO5C,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAiF/D,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,IAAI,GACR,eAAe,CA0CjB;AAED,OAAO,EAAE,0BAA0B,EAAE,CAAC"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/validation.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,0BAA0B,EAC3B,MAAM,oCAAoC,CAAC;AAQ5C,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAiF/D,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,IAAI,GACR,eAAe,CAwDjB;AAED,OAAO,EAAE,0BAA0B,EAAE,CAAC"}
@@ -3,6 +3,7 @@ import entitySchema from "../../public/schemas/entity.js";
3
3
  import relationshipSchema from "../../public/schemas/relationship.js";
4
4
  // implements REQ-kibi-operation-interface-parity
5
5
  import { SYMBOL_ROLES, isAllowedGranularityReason, } from "../../public/symbol-granularity.js";
6
+ import { verificationReceiptHistoryErrors } from "../../public/verification-receipt.js";
6
7
  import { semanticClaimKey } from "../semantic-advisor/clauses.js";
7
8
  import { factKindShapeHints, validateFactModelingShape, valueFieldHint, } from "./strict-fact.js";
8
9
  const ajv = new Ajv({ strict: false });
@@ -84,6 +85,13 @@ export function validateUpsertInput(input, now) {
84
85
  if (!validateEntity(entity)) {
85
86
  throw new Error(`Entity validation failed: ${formatEntityErrors(entity, validateEntity.errors ?? [])}`);
86
87
  }
88
+ if (entity.type === "test" && Array.isArray(entity.verification_receipts)) {
89
+ const receipts = entity.verification_receipts.filter((value) => typeof value === "object" && value !== null && !Array.isArray(value));
90
+ const receiptErrors = verificationReceiptHistoryErrors(input.id, entity.verification_scope, receipts);
91
+ if (receiptErrors.length > 0) {
92
+ throw new Error(`Entity validation failed: ${receiptErrors.join("; ")}`);
93
+ }
94
+ }
87
95
  validateFactModelingShape(entity);
88
96
  if (entity.type === "fact" &&
89
97
  typeof entity.claim_key === "string" &&
@@ -1,5 +1,5 @@
1
1
  import type { SemanticClause } from "./clauses.js";
2
2
  import { type Payload } from "./shared.js";
3
- import type { SemanticAdvisorAnalysisResult, SemanticModelingSuggestion, SemanticSignal } from "./types.js";
4
- export declare function buildAdvisorResult(payload: Payload, signals: readonly SemanticSignal[], modeled: boolean, suggestions: readonly SemanticModelingSuggestion[], clauses: readonly SemanticClause[]): SemanticAdvisorAnalysisResult;
3
+ import type { SemanticAdvisorAnalysisResult, SemanticInterpretationResult, SemanticModelingSuggestion, SemanticProposition, SemanticShadowCue, SemanticSignal } from "./types.js";
4
+ export declare function buildAdvisorResult(payload: Payload, signals: readonly SemanticSignal[], modeled: boolean, suggestions: readonly SemanticModelingSuggestion[], clauses: readonly SemanticClause[], propositions: readonly SemanticProposition[], interpretations: readonly SemanticInterpretationResult[], shadowAnalysis: readonly SemanticShadowCue[]): SemanticAdvisorAnalysisResult;
5
5
  //# sourceMappingURL=analysis-receipt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"analysis-receipt.d.ts","sourceRoot":"","sources":["../../../src/operations/semantic-advisor/analysis-receipt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,KAAK,OAAO,EAA6B,MAAM,aAAa,CAAC;AACtE,OAAO,KAAK,EACV,6BAA6B,EAI7B,0BAA0B,EAC1B,cAAc,EACf,MAAM,YAAY,CAAC;AAwCpB,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,SAAS,cAAc,EAAE,EAClC,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,SAAS,0BAA0B,EAAE,EAClD,OAAO,EAAE,SAAS,cAAc,EAAE,GACjC,6BAA6B,CAqG/B"}
1
+ {"version":3,"file":"analysis-receipt.d.ts","sourceRoot":"","sources":["../../../src/operations/semantic-advisor/analysis-receipt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EACL,KAAK,OAAO,EAMb,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,6BAA6B,EAI7B,4BAA4B,EAC5B,0BAA0B,EAC1B,mBAAmB,EACnB,iBAAiB,EACjB,cAAc,EACf,MAAM,YAAY,CAAC;AA0CpB,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,SAAS,cAAc,EAAE,EAClC,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,SAAS,0BAA0B,EAAE,EAClD,OAAO,EAAE,SAAS,cAAc,EAAE,EAClC,YAAY,EAAE,SAAS,mBAAmB,EAAE,EAC5C,eAAe,EAAE,SAAS,4BAA4B,EAAE,EACxD,cAAc,EAAE,SAAS,iBAAiB,EAAE,GAC3C,6BAA6B,CAkH/B"}
@@ -1,4 +1,4 @@
1
- import { payloadHash, propertiesOf } from "./shared.js";
1
+ import { SEMANTIC_INVENTORY_VERSION, payloadHash, propertiesOf, semanticSourceHash, semanticSourceOf, } from "./shared.js";
2
2
  function chooseLane(signals) {
3
3
  if (signals.some(({ kind }) => kind === "numeric_cardinality" || kind === "numeric_threshold"))
4
4
  return "strict_property";
@@ -19,15 +19,20 @@ function summary(readiness, lane) {
19
19
  return "Requirement prose appears to contain scalar, threshold, or cardinality logic that should be modeled with strict facts.";
20
20
  if (lane === "predicate")
21
21
  return "Requirement prose appears to contain relational or behavioral logic that should be modeled with ontology predicates.";
22
+ if (lane === "rule")
23
+ return "Requirement prose has a typed interpretation candidate; validate and persist it as a safe kibi.logic.v1 rule.";
22
24
  return "Requirement prose appears normative but needs review before it can participate in logic checks.";
23
25
  }
24
26
  // implements REQ-mcp-semantic-advisor-preflight
25
- export function buildAdvisorResult(payload, signals, modeled, suggestions, clauses) {
27
+ export function buildAdvisorResult(payload, signals, modeled, suggestions, clauses, propositions, interpretations, shadowAnalysis) {
28
+ const semanticSource = semanticSourceOf(payload);
26
29
  const suggestionLane = suggestions.some(({ kind }) => kind === "strict_property")
27
30
  ? "strict_property"
28
- : suggestions.some(({ kind }) => kind === "predicate")
29
- ? "predicate"
30
- : null;
31
+ : suggestions.some(({ kind }) => kind === "rule")
32
+ ? "rule"
33
+ : suggestions.some(({ kind }) => kind === "predicate")
34
+ ? "predicate"
35
+ : null;
31
36
  const candidateLane = modeled
32
37
  ? "none"
33
38
  : (suggestionLane ?? chooseLane(signals));
@@ -42,21 +47,22 @@ export function buildAdvisorResult(payload, signals, modeled, suggestions, claus
42
47
  ? ["kb_model_requirement"]
43
48
  : candidateLane === "predicate"
44
49
  ? ["kb_suggest_predicates"]
45
- : candidateLane === "observation_review"
46
- ? ["kb_model_requirement", "kb_suggest_predicates"]
47
- : [];
48
- const expectedClaimKeys = clauses
49
- .filter((clause) => clause.normative)
50
- .map((clause) => clause.claim_key);
50
+ : candidateLane === "rule"
51
+ ? ["kb_model_requirement"]
52
+ : candidateLane === "observation_review"
53
+ ? ["kb_model_requirement", "kb_suggest_predicates"]
54
+ : [];
55
+ const expectedClaimKeys = propositions
56
+ .filter(({ role }) => !["rationale", "example", "subjective"].includes(role))
57
+ .map(({ claim_key }) => claim_key);
51
58
  const rawDeclaredClaimKeys = propertiesOf(payload).logic_claims;
52
59
  const declaredClaimKeys = Array.isArray(rawDeclaredClaimKeys)
53
60
  ? rawDeclaredClaimKeys.filter((value) => typeof value === "string")
54
61
  : [];
55
62
  const missingClaimKeys = expectedClaimKeys.filter((claimKey) => !declaredClaimKeys.includes(claimKey));
56
- const unresolvedClaimKeys = suggestions
57
- .filter((suggestion) => suggestion.kind === "ambiguity_observation" ||
58
- suggestion.kind === "ontology_gap")
59
- .map((suggestion) => suggestion.claim_key);
63
+ const unresolvedClaimKeys = propositions
64
+ .filter(({ status }) => ["ambiguous", "ontology_gap", "missing"].includes(status))
65
+ .map(({ claim_key }) => claim_key);
60
66
  const coverageStatus = expectedClaimKeys.length === 0
61
67
  ? "not_applicable"
62
68
  : modeled
@@ -65,8 +71,13 @@ export function buildAdvisorResult(payload, signals, modeled, suggestions, claus
65
71
  ? "unverified"
66
72
  : "partial";
67
73
  const receipt = {
68
- version: "semantic-advisor-v1",
74
+ version: "semantic-advisor-v2",
69
75
  payload_hash: payloadHash(payload),
76
+ inventory_contract: {
77
+ version: SEMANTIC_INVENTORY_VERSION,
78
+ source_field: semanticSource.field,
79
+ source_hash: semanticSourceHash(semanticSource.text),
80
+ },
70
81
  logic_readiness: readiness,
71
82
  candidate_lane: candidateLane,
72
83
  signals,
@@ -86,6 +97,9 @@ export function buildAdvisorResult(payload, signals, modeled, suggestions, claus
86
97
  ],
87
98
  message: "Numeric cardinality prose can mean an exact count, an upper/lower bound, named membership, or an example; model it explicitly before relying on contradiction checks.",
88
99
  })),
100
+ propositions,
101
+ interpretations,
102
+ shadow_analysis: shadowAnalysis,
89
103
  suggestions,
90
104
  clauses: clauses.map((clause) => ({
91
105
  ...clause,
@@ -1,5 +1,5 @@
1
1
  import type { SemanticAdvisorAnalysisResult, SemanticAdvisorInput } from "./types.js";
2
- export declare const SEMANTIC_ADVISOR_VERSION = "semantic-advisor-v1";
2
+ export declare const SEMANTIC_ADVISOR_VERSION = "semantic-advisor-v2";
3
3
  export { semanticClaimKey } from "./clauses.js";
4
4
  export declare function analyzeSemanticAdvisorInput(input: SemanticAdvisorInput): SemanticAdvisorAnalysisResult;
5
5
  //# sourceMappingURL=analyze-prose.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"analyze-prose.d.ts","sourceRoot":"","sources":["../../../src/operations/semantic-advisor/analyze-prose.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EACV,6BAA6B,EAC7B,oBAAoB,EAKrB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,wBAAwB,wBAAwB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAsThD,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,oBAAoB,GAC1B,6BAA6B,CAuB/B"}
1
+ {"version":3,"file":"analyze-prose.d.ts","sourceRoot":"","sources":["../../../src/operations/semantic-advisor/analyze-prose.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EACV,6BAA6B,EAC7B,oBAAoB,EAWrB,MAAM,YAAY,CAAC;AAEpB,eAAO,MAAM,wBAAwB,wBAAwB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AA01BhD,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,oBAAoB,GAC1B,6BAA6B,CA+D/B"}