kibi-cli 2.19.0 → 2.20.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 (85) hide show
  1. package/dist/cli-operation-metadata.d.ts +1 -1
  2. package/dist/cli-operation-metadata.js +1 -1
  3. package/dist/cli-register-maintenance.js +1 -1
  4. package/dist/commands/engine.d.ts +2 -1
  5. package/dist/commands/engine.d.ts.map +1 -1
  6. package/dist/commands/engine.js +6 -1
  7. package/dist/engine.d.ts.map +1 -1
  8. package/dist/engine.js +24 -6
  9. package/dist/intent-search.d.ts +7 -0
  10. package/dist/intent-search.d.ts.map +1 -1
  11. package/dist/intent-search.js +66 -4
  12. package/dist/operations/modeling/predicate-applicability.d.ts.map +1 -1
  13. package/dist/operations/modeling/predicate-applicability.js +10 -4
  14. package/dist/operations/modeling/predicate-applyplan.d.ts.map +1 -1
  15. package/dist/operations/modeling/predicate-applyplan.js +16 -5
  16. package/dist/operations/modeling/predicate-catalog-4.d.ts.map +1 -1
  17. package/dist/operations/modeling/predicate-catalog-4.js +3 -0
  18. package/dist/operations/modeling/predicate-inference-1.d.ts.map +1 -1
  19. package/dist/operations/modeling/predicate-inference-1.js +34 -7
  20. package/dist/operations/modeling/predicate-score-3.js +1 -1
  21. package/dist/operations/modeling/predicate-types.d.ts +6 -0
  22. package/dist/operations/modeling/predicate-types.d.ts.map +1 -1
  23. package/dist/operations/modeling/suggest-predicates.d.ts.map +1 -1
  24. package/dist/operations/modeling/suggest-predicates.js +111 -0
  25. package/dist/operations/mutation/types.d.ts +26 -0
  26. package/dist/operations/mutation/types.d.ts.map +1 -1
  27. package/dist/operations/mutation/upsert.d.ts.map +1 -1
  28. package/dist/operations/mutation/upsert.js +8 -2
  29. package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
  30. package/dist/operations/mutation/validate-upsert.js +116 -4
  31. package/dist/operations/mutation/warnings.d.ts +10 -0
  32. package/dist/operations/mutation/warnings.d.ts.map +1 -1
  33. package/dist/operations/mutation/warnings.js +26 -0
  34. package/dist/operations/mutation/what-if.d.ts +25 -0
  35. package/dist/operations/mutation/what-if.d.ts.map +1 -0
  36. package/dist/operations/mutation/what-if.js +59 -0
  37. package/dist/operations/planning/compile-intent.d.ts +15 -20
  38. package/dist/operations/planning/compile-intent.d.ts.map +1 -1
  39. package/dist/operations/planning/compile-intent.js +64 -53
  40. package/dist/operations/semantic-advisor/clauses.d.ts.map +1 -1
  41. package/dist/operations/semantic-advisor/clauses.js +8 -7
  42. package/dist/prolog/janitor.d.ts +26 -2
  43. package/dist/prolog/janitor.d.ts.map +1 -1
  44. package/dist/prolog/janitor.js +55 -3
  45. package/dist/prolog/store-lock.d.ts +28 -3
  46. package/dist/prolog/store-lock.d.ts.map +1 -1
  47. package/dist/prolog/store-lock.js +103 -12
  48. package/dist/public/operations/catalog.d.ts +47 -3
  49. package/dist/public/operations/catalog.d.ts.map +1 -1
  50. package/dist/public/operations/check-executor.d.ts +2 -2
  51. package/dist/public/operations/check-executor.d.ts.map +1 -1
  52. package/dist/public/operations/check-executor.js +35 -0
  53. package/dist/public/operations/check-format-shared.d.ts +16 -0
  54. package/dist/public/operations/check-format-shared.d.ts.map +1 -1
  55. package/dist/public/operations/check-format-shared.js +19 -0
  56. package/dist/public/operations/contracts.d.ts.map +1 -1
  57. package/dist/public/operations/contracts.js +10 -0
  58. package/dist/public/operations/discovery-executors.d.ts +3 -0
  59. package/dist/public/operations/discovery-executors.d.ts.map +1 -1
  60. package/dist/public/operations/discovery-executors.js +7 -2
  61. package/dist/public/operations/specs/composite.d.ts +1 -1
  62. package/dist/public/operations/specs/composite.js +1 -1
  63. package/dist/public/operations/specs/discovery.d.ts +2 -2
  64. package/dist/public/operations/specs/discovery.d.ts.map +1 -1
  65. package/dist/public/operations/specs/discovery.js +2 -2
  66. package/dist/public/operations/specs/upsert.d.ts +44 -0
  67. package/dist/public/operations/specs/upsert.d.ts.map +1 -1
  68. package/dist/public/operations/specs/upsert.js +14 -0
  69. package/dist/public/skills/kibi-usage/SKILL.md +36 -1
  70. package/dist/public/skills/kibi-usage/resources/fact-lanes.md +4 -2
  71. package/dist/search-answer.d.ts +13 -0
  72. package/dist/search-answer.d.ts.map +1 -1
  73. package/dist/search-answer.js +45 -4
  74. package/dist/utils/branch-store.d.ts.map +1 -1
  75. package/dist/utils/branch-store.js +4 -2
  76. package/package.json +3 -3
  77. package/src/public/operations/check-executor.ts +44 -1
  78. package/src/public/operations/check-format-shared.ts +35 -1
  79. package/src/public/operations/contracts.ts +11 -0
  80. package/src/public/operations/discovery-executors.ts +12 -2
  81. package/src/public/operations/specs/composite.ts +1 -1
  82. package/src/public/operations/specs/discovery.ts +3 -2
  83. package/src/public/operations/specs/upsert.ts +15 -0
  84. package/src/public/skills/kibi-usage/SKILL.md +36 -1
  85. package/src/public/skills/kibi-usage/resources/fact-lanes.md +4 -2
@@ -1,6 +1,7 @@
1
1
  import { escapeAtom } from "../../prolog/codec.js";
2
2
  import { loadEntities } from "../../public/operations/discovery-entities.js";
3
3
  import { parsePrologList } from "../mutation/serialization.js";
4
+ import { compileGroundingPlan } from "../planning/compile-intent.js";
4
5
  import { analyzeSemanticAdvisorInput } from "../semantic-advisor/analyze-prose.js";
5
6
  import { semanticClaimKey } from "../semantic-advisor/clauses.js";
6
7
  import { composeOntologyCatalogForOperation } from "../semantic-advisor/plugin-orchestration.js";
@@ -51,6 +52,7 @@ function compoundInputAbstention(args, text, subject, propositionCount) {
51
52
  recommendedPredicateSchema: null,
52
53
  applyPlan,
53
54
  relationshipPlan: null,
55
+ plan: null,
54
56
  warnings: [warning],
55
57
  },
56
58
  applyPlan,
@@ -79,6 +81,7 @@ function nonlogicalInputRouting(args, text, subject) {
79
81
  recommendedPredicateSchema: null,
80
82
  applyPlan,
81
83
  relationshipPlan: null,
84
+ plan: null,
82
85
  warnings: [warning],
83
86
  },
84
87
  applyPlan,
@@ -414,6 +417,17 @@ export async function handleKbSuggestPredicates(prolog, args, context) {
414
417
  ? "No predicate candidate passed the semantic applicability gate; keep the existing grounding and record the ontology-gap observation in applyPlan so the missing schema stays visible."
415
418
  : "No predicate candidate passed the semantic applicability gate; record an ontology gap and review the generated schema draft instead of silently writing prose.");
416
419
  const logicClaims = Array.from(new Set([...(args.existingLogicClaims ?? []), claimKey]));
420
+ const plan = relationshipPlan !== null && plannedFactId !== null && args.requirementId
421
+ ? await groundingPlan(prolog, context, {
422
+ requirementId: args.requirementId,
423
+ claimKey,
424
+ text,
425
+ factStep: predicatePlan[0] ?? {},
426
+ relationship: relationshipPlan.relationship,
427
+ logicClaims,
428
+ warnings,
429
+ })
430
+ : null;
417
431
  return {
418
432
  content: [{ type: "text", text: textSummary }],
419
433
  structuredContent: {
@@ -428,6 +442,7 @@ export async function handleKbSuggestPredicates(prolog, args, context) {
428
442
  recommendedPredicateSchema,
429
443
  applyPlan,
430
444
  relationshipPlan,
445
+ plan,
431
446
  relationshipTarget,
432
447
  existingGrounding,
433
448
  replacementPlan,
@@ -459,6 +474,102 @@ const RESTATED_REQUIREMENT_FIELDS = [
459
474
  "owner",
460
475
  "tags",
461
476
  ];
477
+ // implements REQ-model-what-if-planned-facts
478
+ /**
479
+ * The hash-bound plan behind applyPlan + relationshipPlan: the predicate fact,
480
+ * then the requirement restated with the merged logic_claims manifest and the
481
+ * requires_predicate link. kb_apply_plan applies both in one transaction, and
482
+ * the plan's contradictionAnalysis says what the batch would introduce.
483
+ */
484
+ async function groundingPlan(prolog, context, input) {
485
+ if (prolog === null || context === undefined)
486
+ return null;
487
+ const stored = await storedRequirementContract(prolog, input.requirementId, input.warnings);
488
+ if (stored === null) {
489
+ input.warnings.push(`No hash-bound plan: requirement ${input.requirementId} is not stored, so its upsert step cannot restate the stored title and status. Apply applyPlan and relationshipPlan with kb_upsert.`);
490
+ return null;
491
+ }
492
+ // A stored ledger is restated with this claim marked modeled, so the
493
+ // proposition-complete check sees one modeled entry per grounding link.
494
+ // A claim the ledger does not carry cannot be grounded by this plan.
495
+ const inventory = Array.isArray(stored.semantic_inventory)
496
+ ? stored.semantic_inventory
497
+ : null;
498
+ if (inventory !== null) {
499
+ const entry = inventory.find((row) => row !== null &&
500
+ typeof row === "object" &&
501
+ row.claim_key === input.claimKey);
502
+ if (entry === undefined) {
503
+ input.warnings.push(`No hash-bound plan: the ledger of ${input.requirementId} has no proposition ${input.claimKey} for this text. Run kb_model mode analyze with the requirement's complete prose and pass one of its clauses as text; applyPlan can still be written with kb_upsert.`);
504
+ return null;
505
+ }
506
+ stored.semantic_inventory = inventory.map((row) => row === entry
507
+ ? {
508
+ ...entry,
509
+ status: "modeled",
510
+ reason: `Grounded by the ${String(input.factStep.id)} predicate fact this plan writes.`,
511
+ }
512
+ : row);
513
+ }
514
+ try {
515
+ const plan = await compileGroundingPlan(context, prolog, {
516
+ requirementId: input.requirementId,
517
+ claimKey: input.claimKey,
518
+ text: input.text,
519
+ steps: [
520
+ input.factStep,
521
+ {
522
+ type: "req",
523
+ id: input.requirementId,
524
+ properties: { ...stored, logic_claims: [...input.logicClaims] },
525
+ relationships: [input.relationship],
526
+ },
527
+ ],
528
+ });
529
+ if (plan.status === "blocked") {
530
+ const reasons = plan.contradictionAnalysis.witnesses
531
+ .map((witness) => witness.reason)
532
+ .filter(Boolean);
533
+ input.warnings.push(`Applying this grounding would contradict the current KB, so plan.status is blocked: ${reasons.join("; ")}. Supersede or close the conflicting requirement before grounding this claim.`);
534
+ }
535
+ else if (plan.status !== "ready") {
536
+ input.warnings.push(`The hash-bound plan needs resolution before kb_apply_plan can run it: ${plan.diagnostics.join("; ")}`);
537
+ }
538
+ return plan;
539
+ }
540
+ catch (error) {
541
+ input.warnings.push(`No hash-bound plan could be compiled (${error instanceof Error ? error.message : String(error)}); apply applyPlan and relationshipPlan with kb_upsert.`);
542
+ return null;
543
+ }
544
+ }
545
+ const STORED_LEDGER_FIELDS = [
546
+ "text_ref",
547
+ "semantic_text",
548
+ "semantic_clauses",
549
+ "semantic_inventory",
550
+ "semantic_inventory_version",
551
+ "semantic_source_field",
552
+ "semantic_source_hash",
553
+ ];
554
+ // implements REQ-model-what-if-planned-facts
555
+ /**
556
+ * The stored requirement as a plan step restates it: title, status and
557
+ * metadata plus its proposition ledger, so the upsert kb_apply_plan runs is
558
+ * validated as given and keeps the ledger instead of replacing it.
559
+ */
560
+ async function storedRequirementContract(prolog, requirementId, warnings) {
561
+ const restated = await storedRequirementProperties(prolog, requirementId, warnings);
562
+ if (restated === null)
563
+ return null;
564
+ const [stored] = await loadEntities(prolog, {
565
+ id: requirementId,
566
+ type: "req",
567
+ });
568
+ for (const field of STORED_LEDGER_FIELDS)
569
+ if (stored?.[field] !== undefined && stored[field] !== null)
570
+ restated[field] = stored[field];
571
+ return restated;
572
+ }
462
573
  /**
463
574
  * The requirement fields the replacement's requirement upsert restates, so
464
575
  * the step is a complete kb_upsert payload (title and status are required)
@@ -14,9 +14,23 @@ export type UpsertInput = {
14
14
  };
15
15
  /** Validate and preview the write without mutating the KB. */
16
16
  readonly dryRun?: boolean;
17
+ /**
18
+ * Dry run only: fact upserts an earlier step will write before this one
19
+ * (the kb_model applyPlan entries). They are validated in order and staged
20
+ * with the payload, so grounding targets resolve and the contradiction
21
+ * preview sees the KB as it would be after the whole batch.
22
+ */
23
+ readonly plannedFacts?: readonly PlannedFactInput[];
17
24
  readonly _skipContradictionCheck?: boolean;
18
25
  readonly _requestId?: string;
19
26
  };
27
+ /** One planned fact write staged ahead of a dry run. */
28
+ export type PlannedFactInput = {
29
+ readonly type: string;
30
+ readonly id: string;
31
+ readonly properties: Readonly<Record<string, unknown>>;
32
+ readonly relationships?: readonly RelationshipInput[];
33
+ };
20
34
  /**
21
35
  * Store state an upsert's validation must see in addition to the live KB:
22
36
  * what earlier steps of the same plan will have written by the time this
@@ -84,6 +98,18 @@ export type ValidateUpsertPayload = {
84
98
  readonly warnings: readonly string[];
85
99
  readonly semanticAdvisor: SemanticAdvisorReceipt | null;
86
100
  readonly normalizedPreview: Readonly<Record<string, unknown>> | null;
101
+ /** Planned fact ids staged ahead of the payload, in order. */
102
+ readonly stagedFacts?: readonly string[];
103
+ /**
104
+ * With plannedFacts: the contradiction and scenario-feasibility witnesses
105
+ * the KB would hold after the planned facts and this payload, split into
106
+ * what the batch introduces, removes and leaves unchanged.
107
+ */
108
+ readonly whatIf?: Readonly<{
109
+ introduced: readonly Readonly<Record<string, unknown>>[];
110
+ removed: readonly Readonly<Record<string, unknown>>[];
111
+ unchanged: readonly Readonly<Record<string, unknown>>[];
112
+ }>;
87
113
  };
88
114
  export type DeleteInput = {
89
115
  readonly ids?: readonly string[];
@@ -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":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"upsert.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/upsert.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AACjF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAUxE,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AA8BnF,OAAO,EACL,KAAK,kBAAkB,EAExB,MAAM,oBAAoB,CAAC;AAQ5B,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,eAAe,EAChB,MAAM,YAAY,CAAC;AA6CpB,wBAAgB,gCAAgC,CAC9C,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,GAChB,IAAI,CAkBN;AAwCD,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,OAAO,EAAE,gBAAgB,EACzB,MAAM,CAAC,EAAE,iBAAiB,GACzB,OAAO,CAAC,IAAI,CAAC,CAqBf;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,EACzB,MAAM,CAAC,EAAE,iBAAiB,EAC1B,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC,CA8BvC;AAmCD,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,kEAAkE;IAClE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IACtC;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC;CACrC,CAAC,CAAC;AAGH,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,yEAAyE;IACzE,QAAQ,CAAC,aAAa,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACrD,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC,OAAO,2BAA2B,CAAC,CAAC;CACnE,CAAC,CAAC;AAGH;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,gBAAgB,EACzB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,gBAAgB,CAAC,CAgF3B;AAGD,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAC5C;;;;;;OAMG;IAEH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IACzC;;;;OAIG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IACtC;;;;OAIG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;CACxC,CAAC,CAAC;AAyBH,wBAAsB,aAAa,CACjC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,gBAAgB,EACzB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CA4gBzC"}
1
+ {"version":3,"file":"upsert.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/upsert.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AACjF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAUxE,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AA8BnF,OAAO,EACL,KAAK,kBAAkB,EAExB,MAAM,oBAAoB,CAAC;AAQ5B,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,eAAe,EAChB,MAAM,YAAY,CAAC;AAgDpB,wBAAgB,gCAAgC,CAC9C,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,MAAM,GAChB,IAAI,CAkBN;AAwCD,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,OAAO,EAAE,gBAAgB,EACzB,MAAM,CAAC,EAAE,iBAAiB,GACzB,OAAO,CAAC,IAAI,CAAC,CAqBf;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,EACzB,MAAM,CAAC,EAAE,iBAAiB,EAC1B,MAAM,CAAC,EAAE,kBAAkB,GAC1B,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC,CA8BvC;AAmCD,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,kEAAkE;IAClE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IACtC;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,iBAAiB,CAAC;CACrC,CAAC,CAAC;AAGH,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC,yEAAyE;IACzE,QAAQ,CAAC,aAAa,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACrD,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC,OAAO,2BAA2B,CAAC,CAAC;CACnE,CAAC,CAAC;AAGH;;;;;;;;GAQG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,gBAAgB,EACzB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,gBAAgB,CAAC,CAgF3B;AAGD,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAC5C;;;;;;OAMG;IAEH,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IACzC;;;;OAIG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IACtC;;;;OAIG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;CACxC,CAAC,CAAC;AAyBH,wBAAsB,aAAa,CACjC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,gBAAgB,EACzB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC,CAyhBzC"}
@@ -26,7 +26,7 @@ import { acquireSymbolCompilerLock, releaseSymbolCompilerLock, } from "./symbol-
26
26
  import { validateSymbolGranularity } from "./symbol-granularity.js";
27
27
  import { refreshSymbolCoordinatesForManifest } from "./symbol-refresh.js";
28
28
  import { validateUpsertInput } from "./validation.js";
29
- import { scenarioCoverageWarnings } from "./warnings.js";
29
+ import { scenarioCoverageWarnings, symbolCoverageWarnings, } from "./warnings.js";
30
30
  import { acquireWorkspaceMutationLock, releaseWorkspaceMutationLock, } from "./workspace-mutation-lock.js";
31
31
  function requireProlog(context) {
32
32
  if (context.prolog === undefined) {
@@ -250,6 +250,9 @@ async function dryRunUpsert(input, context) {
250
250
  export async function executeUpsert(input, context, options = {}) {
251
251
  if (input.dryRun === true)
252
252
  return dryRunUpsert(input, context);
253
+ // implements REQ-model-what-if-planned-facts
254
+ if (input.plannedFacts !== undefined)
255
+ throw new Error(`Upsert of ${input.id} rejected: plannedFacts is a dryRun-only input. Write the planned facts first (kb_upsert each, or kb_apply_plan with the kb_model plan), then upsert ${input.id} without plannedFacts.`);
253
256
  const branchAttachment = context.branchAttachment ?? resolveBranchAttachment(context.workspaceRoot);
254
257
  if ("error" in branchAttachment) {
255
258
  throw new Error(`Unable to resolve KB branch: ${branchAttachment.error}`);
@@ -481,7 +484,10 @@ export async function executeUpsert(input, context, options = {}) {
481
484
  if (changeKind === null) {
482
485
  throw new Error(`Upsert commit completed without a created/updated result for ${input.id}`);
483
486
  }
484
- const coverage = await scenarioCoverageWarnings(prolog, validated.relationships, input.type, input.id);
487
+ const coverage = [
488
+ ...(await scenarioCoverageWarnings(prolog, validated.relationships, input.type, input.id)),
489
+ ...(await symbolCoverageWarnings(prolog, validated.relationships, input.type, input.id)),
490
+ ];
485
491
  const created = changeKind === "created" ? 1 : 0;
486
492
  const idStyleWarnings = created === 1
487
493
  ? entityIdStyleWarnings({
@@ -1 +1 @@
1
- {"version":3,"file":"validate-upsert.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/validate-upsert.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,gBAAgB,EAEjB,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAWxE,OAAO,KAAK,EAEV,WAAW,EACX,qBAAqB,EACtB,MAAM,YAAY,CAAC;AA2EpB;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,qBAAqB,CAAC,CAAC,CAuEjD"}
1
+ {"version":3,"file":"validate-upsert.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/validate-upsert.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,gBAAgB,EAEjB,MAAM,0CAA0C,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAYxE,OAAO,KAAK,EAIV,WAAW,EACX,qBAAqB,EACtB,MAAM,YAAY,CAAC;AA2MpB;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,qBAAqB,CAAC,CAAC,CAgHjD"}
@@ -4,11 +4,13 @@ import { entityIdStyleWarnings } from "../../utils/entity-id-style.js";
4
4
  import { analyzeSemanticAdvisorInput } from "../semantic-advisor/analyze-prose.js";
5
5
  import { assertSemanticInventoryBoundary } from "../semantic-advisor/ingestion-boundary.js";
6
6
  import { entityContextWarnings } from "./context-warning.js";
7
- import { buildUpsertContradictionPreviewGoal, formatUpsertError, } from "./contradictions.js";
7
+ import { buildUpsertContradictionPreviewGoal, buildWhatIfAnalysisGoal, formatUpsertError, } from "./contradictions.js";
8
8
  import { validateRelationshipSources } from "./relationships.js";
9
9
  import { validateSymbolGranularity } from "./symbol-granularity.js";
10
10
  import { validateAppendOnlyProofReceipts, validateUpsertForCommit, } from "./upsert.js";
11
11
  import { validateUpsertInput } from "./validation.js";
12
+ import { symbolCoverageWarnings } from "./warnings.js";
13
+ import { isBlockingWitness, parseWhatIfAnalysis } from "./what-if.js";
12
14
  // implements REQ-kibi-entity-id-style
13
15
  async function entityExists(prolog, id) {
14
16
  const result = await prolog.query(`once(kb_entity('${escapeAtom(id)}', _Type, _Props))`);
@@ -33,6 +35,92 @@ async function previewContradictions(prolog, input, entity, relationships) {
33
35
  throw new Error(formatUpsertError(input.id, preview.error, preview.errorRecord));
34
36
  }
35
37
  }
38
+ // implements REQ-model-what-if-planned-facts
39
+ /**
40
+ * Validate the planned facts in order, each against the live store plus the
41
+ * facts before it, exactly as kb_apply_plan validates a plan's steps. The
42
+ * result is the staged state the payload's own validation reads: a planned
43
+ * fact counts as a live relationship target and its claim_key is read from
44
+ * the plan, so a requirement can be previewed before its facts are written.
45
+ */
46
+ async function stagePlannedFacts(input, context) {
47
+ const planned = input.plannedFacts;
48
+ if (planned === undefined)
49
+ return null;
50
+ if (!Array.isArray(planned))
51
+ throw new Error("plannedFacts must be an array of fact upsert payloads");
52
+ const entities = new Map();
53
+ const relationships = [];
54
+ const steps = [];
55
+ for (const [index, fact] of planned.entries()) {
56
+ const id = typeof fact?.id === "string" ? fact.id : `#${index + 1}`;
57
+ if (fact?.type !== "fact")
58
+ throw new Error(`planned fact ${id} is invalid: plannedFacts stages fact entities only (got type '${String(fact?.type)}')`);
59
+ if (fact.id === input.id)
60
+ throw new Error(`planned fact ${id} is invalid: it has the same id as the payload`);
61
+ try {
62
+ const { validated } = await validateUpsertForCommit(plannedFactUpsert(fact), context, { staged: { entities, relationships: [...relationships] } });
63
+ entities.set(fact.id, validated.entity);
64
+ relationships.push(...validated.relationships);
65
+ steps.push({
66
+ entity: validated.entity,
67
+ relationships: validated.relationships,
68
+ });
69
+ }
70
+ catch (error) {
71
+ throw new Error(`planned fact ${id} is invalid: ${error instanceof Error ? error.message : String(error)}`);
72
+ }
73
+ }
74
+ return { staged: { entities, relationships }, steps };
75
+ }
76
+ function plannedFactUpsert(fact) {
77
+ return {
78
+ type: fact.type,
79
+ id: fact.id,
80
+ properties: fact.properties,
81
+ ...(fact.relationships !== undefined
82
+ ? { relationships: fact.relationships }
83
+ : {}),
84
+ };
85
+ }
86
+ // implements REQ-model-what-if-planned-facts, REQ-kibi-truthful-consistency
87
+ /**
88
+ * The contradiction preview for a payload with planned facts: the facts and
89
+ * the payload are staged together in a rolled-back transaction and the
90
+ * witnesses the KB would then hold are compared with the current KB's. A
91
+ * blocking witness the batch introduces refuses the dry run the way the
92
+ * commit would refuse the last write of the batch; the full split is
93
+ * returned so an agent sees the conflict before any fact exists.
94
+ */
95
+ async function previewStagedContradictions(prolog, input, entity, relationships, facts) {
96
+ const result = await prolog.query(buildWhatIfAnalysisGoal([
97
+ ...facts.steps.map((step) => ({
98
+ entity: step.entity,
99
+ relationships: step.relationships,
100
+ skipContradictionCheck: true,
101
+ })),
102
+ { entity, relationships, skipContradictionCheck: true },
103
+ ]));
104
+ if (!result.success)
105
+ throw new Error(formatUpsertError(input.id, result.error, result.errorRecord));
106
+ const analysis = parseWhatIfAnalysis(result.bindings.JsonString);
107
+ if (analysis === null)
108
+ throw new Error(`Failed to preview ${input.id} with planned facts: the staged contradiction analysis could not be read`);
109
+ const skip = input.type !== "req" || input._skipContradictionCheck === true;
110
+ const blocking = skip ? [] : analysis.introduced.filter(isBlockingWitness);
111
+ if (blocking.length > 0) {
112
+ const conflicts = blocking.map((witness) => {
113
+ const others = witness.requirements.filter((id) => id !== input.id);
114
+ return ` - Conflicts with ${others.join(", ") || witness.requirements.join(", ")}: ${witness.reason}`;
115
+ });
116
+ throw new Error(`Contradiction detected for requirement ${input.id} once its planned facts are written:\n${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. (stage=contradiction_check, plannedFacts staged)`);
117
+ }
118
+ return {
119
+ introduced: analysis.introduced,
120
+ removed: analysis.removed,
121
+ unchanged: analysis.unchanged,
122
+ };
123
+ }
36
124
  /**
37
125
  * The validation chain for a runtime without a store: everything that does
38
126
  * not need to read the KB.
@@ -58,12 +146,25 @@ async function validateWithoutStore(input, context) {
58
146
  */
59
147
  export async function executeValidateUpsert(input, context) {
60
148
  try {
149
+ if (input.plannedFacts !== undefined && context.prolog === undefined)
150
+ throw new Error("plannedFacts needs a KB store: the planned facts are staged against the current KB");
151
+ let whatIf;
152
+ let stagedFacts;
153
+ let relationships = input.relationships ?? [];
61
154
  const { entity, semantic } = context.prolog !== undefined
62
- ? await validateUpsertForCommit(input, context).then(async (result) => {
155
+ ? await stagePlannedFacts(input, context).then(async (facts) => {
156
+ const result = await validateUpsertForCommit(input, context, facts === null ? {} : { staged: facts.staged });
63
157
  // The commit goal checks requirement contradictions after the
64
158
  // validations above; a dry run previews that stage as well, so
65
159
  // "valid" means the commit would not refuse the write.
66
- await previewContradictions(context.prolog, input, result.validated.entity, result.validated.relationships);
160
+ if (facts === null) {
161
+ await previewContradictions(context.prolog, input, result.validated.entity, result.validated.relationships);
162
+ }
163
+ else {
164
+ stagedFacts = [...facts.staged.entities.keys()];
165
+ whatIf = await previewStagedContradictions(context.prolog, input, result.validated.entity, result.validated.relationships, facts);
166
+ }
167
+ relationships = result.validated.relationships;
67
168
  return {
68
169
  entity: result.validated.entity,
69
170
  semantic: result.semantic,
@@ -81,22 +182,33 @@ export async function executeValidateUpsert(input, context) {
81
182
  !(await entityExists(context.prolog, input.id))
82
183
  ? candidateIdStyleWarnings
83
184
  : [];
185
+ // The same symbol-coverage warning the write returns, so the dry run
186
+ // tells the agent before the write that kb_check will flag it.
187
+ const coverageWarnings = context.prolog
188
+ ? await symbolCoverageWarnings(context.prolog, relationships, input.type, input.id)
189
+ : [];
84
190
  const payload = {
85
191
  valid: true,
86
192
  errors: [],
87
193
  warnings: [
88
194
  ...semantic.warnings,
195
+ ...coverageWarnings,
89
196
  ...idStyleWarnings,
90
197
  ...entityContextWarnings(input, entity, context.workspaceRoot),
91
198
  ],
92
199
  semanticAdvisor: semantic.receipt,
93
200
  normalizedPreview: entity,
201
+ ...(stagedFacts !== undefined ? { stagedFacts } : {}),
202
+ ...(whatIf !== undefined ? { whatIf } : {}),
94
203
  };
204
+ const stagedNote = stagedFacts === undefined
205
+ ? ""
206
+ : ` ${stagedFacts.length} planned fact(s) were staged ahead of it (${stagedFacts.join(", ")}); the batch introduces ${whatIf?.introduced.length ?? 0} witness(es).`;
95
207
  return {
96
208
  content: [
97
209
  {
98
210
  type: "text",
99
- text: "kb_validate_upsert: payload is valid for kb_upsert preflight checks. No mutation was performed.",
211
+ text: `kb_validate_upsert: payload is valid for kb_upsert preflight checks. No mutation was performed.${stagedNote}`,
100
212
  },
101
213
  ],
102
214
  structuredContent: payload,
@@ -2,4 +2,14 @@ import type { PrologPort } from "../../public/operations/runtime-types.js";
2
2
  import type { RelationshipInput } from "./types.js";
3
3
  export declare function scenarioCoverageWarning(entityId: string): readonly string[];
4
4
  export declare function scenarioCoverageWarnings(prolog: PrologPort, relationships: readonly RelationshipInput[], entityType: string, entityId: string): Promise<readonly string[]>;
5
+ export declare function symbolCoverageWarning(entityId: string): readonly string[];
6
+ /**
7
+ * A production symbol (one that implements a requirement) needs a covered_by
8
+ * edge to a test that covers that requirement, or kb_check reports
9
+ * symbol-coverage once it is written. Warn before and after the write so the
10
+ * agent learns it from the upsert, not from the next check. An executable
11
+ * test symbol (executable_for) is not production code, and a symbol that
12
+ * already has a stored covered_by edge is left for kb_check to judge.
13
+ */
14
+ export declare function symbolCoverageWarnings(prolog: PrologPort, relationships: readonly RelationshipInput[], entityType: string, entityId: string): Promise<readonly string[]>;
5
15
  //# sourceMappingURL=warnings.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"warnings.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/warnings.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAC3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAI3E;AAGD,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,UAAU,EAClB,aAAa,EAAE,SAAS,iBAAiB,EAAE,EAC3C,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAU5B"}
1
+ {"version":3,"file":"warnings.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/warnings.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAC3E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAI3E;AAGD,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,UAAU,EAClB,aAAa,EAAE,SAAS,iBAAiB,EAAE,EAC3C,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAU5B;AAGD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAIzE;AAGD;;;;;;;GAOG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,UAAU,EAClB,aAAa,EAAE,SAAS,iBAAiB,EAAE,EAC3C,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAe5B"}
@@ -17,3 +17,29 @@ export async function scenarioCoverageWarnings(prolog, relationships, entityType
17
17
  }
18
18
  return [];
19
19
  }
20
+ // implements REQ-kibi-operation-interface-parity
21
+ export function symbolCoverageWarning(entityId) {
22
+ return [
23
+ `Production symbol ${entityId} has implements but no covered_by: kb_check will report symbol-coverage. Add covered_by: TEST-<area>-<behavior> to a test that validates the requirement's scenario (or verified_by(req,test) when the requirement has no scenario).`,
24
+ ];
25
+ }
26
+ // implements REQ-kibi-operation-interface-parity
27
+ /**
28
+ * A production symbol (one that implements a requirement) needs a covered_by
29
+ * edge to a test that covers that requirement, or kb_check reports
30
+ * symbol-coverage once it is written. Warn before and after the write so the
31
+ * agent learns it from the upsert, not from the next check. An executable
32
+ * test symbol (executable_for) is not production code, and a symbol that
33
+ * already has a stored covered_by edge is left for kb_check to judge.
34
+ */
35
+ export async function symbolCoverageWarnings(prolog, relationships, entityType, entityId) {
36
+ if (entityType !== "symbol")
37
+ return [];
38
+ const own = relationships.filter((relationship) => relationship.from === undefined || relationship.from === entityId);
39
+ const has = (type) => own.some((relationship) => relationship.type === type);
40
+ if (!has("implements") || has("covered_by") || has("executable_for"))
41
+ return [];
42
+ const id = escapeAtom(entityId);
43
+ const stored = await prolog.query(`once((kb_relationship(covered_by, '${id}', _) ; kb_relationship(executable_for, '${id}', _)))`);
44
+ return stored.success ? [] : symbolCoverageWarning(entityId);
45
+ }
@@ -0,0 +1,25 @@
1
+ /** A contradiction or scenario-infeasibility witness the checker reports. */
2
+ export type ContradictionWitness = Readonly<{
3
+ requirements: readonly string[];
4
+ reason: string;
5
+ status?: string;
6
+ /** property | predicate | rule | scenario_feasibility */
7
+ kind?: string;
8
+ } & Record<string, unknown>>;
9
+ export type WhatIfAnalysis = Readonly<{
10
+ after: readonly ContradictionWitness[];
11
+ introduced: readonly ContradictionWitness[];
12
+ removed: readonly ContradictionWitness[];
13
+ unchanged: readonly ContradictionWitness[];
14
+ }>;
15
+ /**
16
+ * Parse checks:what_if_analysis_json/2 output. The binding is a quoted Prolog
17
+ * string, so the JSON may arrive encoded once more as a JSON string. A bare
18
+ * witness array (the what_if_contradiction_witnesses_json/2 shape) carries no
19
+ * current-KB baseline, so every witness in it is treated as introduced.
20
+ * Returns null when the output cannot be read.
21
+ */
22
+ export declare function parseWhatIfAnalysis(raw: unknown): WhatIfAnalysis | null;
23
+ /** Blocking: a proven contradiction or an infeasible success scenario. */
24
+ export declare function isBlockingWitness(witness: ContradictionWitness): boolean;
25
+ //# sourceMappingURL=what-if.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"what-if.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/what-if.ts"],"names":[],"mappings":"AAGA,6EAA6E;AAC7E,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CACzC;IACE,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAC5B,CAAC;AAGF,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,KAAK,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACvC,UAAU,EAAE,SAAS,oBAAoB,EAAE,CAAC;IAC5C,OAAO,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACzC,SAAS,EAAE,SAAS,oBAAoB,EAAE,CAAC;CAC5C,CAAC,CAAC;AA6BH;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,GAAG,IAAI,CAoBvE;AAGD,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAExE"}
@@ -0,0 +1,59 @@
1
+ import { normalizeEntityId } from "../../prolog/codec.js";
2
+ function text(value) {
3
+ return typeof value === "string" ? value.trim() : "";
4
+ }
5
+ function isRecord(value) {
6
+ return value !== null && typeof value === "object" && !Array.isArray(value);
7
+ }
8
+ function whatIfWitness(witness) {
9
+ return {
10
+ ...witness,
11
+ requirements: Array.isArray(witness.requirements)
12
+ ? witness.requirements.map((id) => normalizeEntityId(String(id)))
13
+ : [],
14
+ reason: text(witness.reason),
15
+ status: text(witness.status) || "contradiction",
16
+ ...(typeof witness.kind === "string" ? { kind: witness.kind } : {}),
17
+ };
18
+ }
19
+ function whatIfWitnesses(value) {
20
+ return (Array.isArray(value) ? value.filter(isRecord) : []).map(whatIfWitness);
21
+ }
22
+ // implements REQ-kibi-truthful-consistency
23
+ /**
24
+ * Parse checks:what_if_analysis_json/2 output. The binding is a quoted Prolog
25
+ * string, so the JSON may arrive encoded once more as a JSON string. A bare
26
+ * witness array (the what_if_contradiction_witnesses_json/2 shape) carries no
27
+ * current-KB baseline, so every witness in it is treated as introduced.
28
+ * Returns null when the output cannot be read.
29
+ */
30
+ export function parseWhatIfAnalysis(raw) {
31
+ if (typeof raw !== "string")
32
+ return null;
33
+ let parsed;
34
+ try {
35
+ parsed = JSON.parse(raw);
36
+ if (typeof parsed === "string")
37
+ parsed = JSON.parse(parsed);
38
+ }
39
+ catch {
40
+ return null;
41
+ }
42
+ if (Array.isArray(parsed)) {
43
+ const after = whatIfWitnesses(parsed);
44
+ return { after, introduced: after, removed: [], unchanged: [] };
45
+ }
46
+ if (!isRecord(parsed))
47
+ return null;
48
+ return {
49
+ after: whatIfWitnesses(parsed.after),
50
+ introduced: whatIfWitnesses(parsed.introduced),
51
+ removed: whatIfWitnesses(parsed.removed),
52
+ unchanged: whatIfWitnesses(parsed.unchanged),
53
+ };
54
+ }
55
+ // implements REQ-kibi-truthful-consistency
56
+ /** Blocking: a proven contradiction or an infeasible success scenario. */
57
+ export function isBlockingWitness(witness) {
58
+ return witness.status === "contradiction" || witness.status === "infeasible";
59
+ }
@@ -1,5 +1,6 @@
1
1
  import { type IntentSearchFacets, type IntentSearchMatch, type SourceLocation } from "../../intent-search.js";
2
2
  import type { OperationContext } from "../../public/operations/runtime-types.js";
3
+ import { type ContradictionWitness } from "../mutation/what-if.js";
3
4
  import type { SemanticInterpretationInput } from "../semantic-advisor/types.js";
4
5
  export declare const COMPILE_PLAN_VERSION: "kibi.compile-plan.v1";
5
6
  export type CompileIntentArgs = Readonly<{
@@ -47,13 +48,8 @@ export type ProposalDecision = Readonly<{
47
48
  * (sides, facts, scenario, comparison) is kept alongside these normalized
48
49
  * fields so callers can act on more than requirement ids.
49
50
  */
50
- export type ContradictionWitness = Readonly<{
51
- requirements: readonly string[];
52
- reason: string;
53
- status?: string;
54
- /** property | predicate | rule | scenario_feasibility */
55
- kind?: string;
56
- } & Record<string, unknown>>;
51
+ export type { ContradictionWitness, WhatIfAnalysis, } from "../mutation/what-if.js";
52
+ export { isBlockingWitness, parseWhatIfAnalysis } from "../mutation/what-if.js";
57
53
  export type TraceabilityProposal = Readonly<{
58
54
  proposalId: string;
59
55
  candidateId: string;
@@ -173,22 +169,21 @@ export type SourceWritePlan = Readonly<{
173
169
  }>;
174
170
  /** Rolled-back staging goal for a plan's steps (see what_if_analysis/2). */
175
171
  export declare function planWhatIfGoal(steps: readonly PlanStep[], now: Date): string;
176
- export type WhatIfAnalysis = Readonly<{
177
- after: readonly ContradictionWitness[];
178
- introduced: readonly ContradictionWitness[];
179
- removed: readonly ContradictionWitness[];
180
- unchanged: readonly ContradictionWitness[];
172
+ export type GroundingPlanInput = Readonly<{
173
+ requirementId: string;
174
+ claimKey: string;
175
+ text: string;
176
+ /** The fact write(s), then the requirement upsert that links them. */
177
+ steps: readonly PlanStep[];
181
178
  }>;
182
179
  /**
183
- * Parse checks:what_if_analysis_json/2 output. The binding is a quoted Prolog
184
- * string, so the JSON may arrive encoded once more as a JSON string. A bare
185
- * witness array (the what_if_contradiction_witnesses_json/2 shape) carries no
186
- * current-KB baseline, so every witness in it is treated as introduced.
187
- * Returns null when the output cannot be read.
180
+ * A hash-bound compile plan for a grounding kb_model planned: the predicate
181
+ * fact and the requirement upsert that links it, validated and applied
182
+ * together by kb_apply_plan. Its contradiction analysis is the what-if over
183
+ * the current KB plus these steps, so a decision conflict with a fact that is
184
+ * already stored is reported here, before any write, and blocks the plan.
188
185
  */
189
- export declare function parseWhatIfAnalysis(raw: unknown): WhatIfAnalysis | null;
190
- /** Blocking: a proven contradiction or an infeasible success scenario. */
191
- export declare function isBlockingWitness(witness: ContradictionWitness): boolean;
186
+ export declare function compileGroundingPlan(context: OperationContext, prolog: NonNullable<OperationContext["prolog"]>, input: GroundingPlanInput): Promise<CompilePlanV1>;
192
187
  export declare function executeCompileIntent(args: CompileIntentArgs, context: OperationContext): Promise<{
193
188
  content: Array<{
194
189
  type: "text";