kibi-cli 2.16.0 → 2.18.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 (83) hide show
  1. package/dist/cli-protocol.d.ts.map +1 -1
  2. package/dist/cli-protocol.js +13 -0
  3. package/dist/cli-register-proof.d.ts +6 -0
  4. package/dist/cli-register-proof.d.ts.map +1 -1
  5. package/dist/cli-register-proof.js +46 -2
  6. package/dist/commands/doctor.d.ts.map +1 -1
  7. package/dist/commands/doctor.js +9 -3
  8. package/dist/commands/sync/untracked-targets.d.ts.map +1 -1
  9. package/dist/commands/sync/untracked-targets.js +39 -9
  10. package/dist/commands/sync.d.ts.map +1 -1
  11. package/dist/commands/sync.js +26 -5
  12. package/dist/engine.d.ts +4 -0
  13. package/dist/engine.d.ts.map +1 -1
  14. package/dist/engine.js +40 -10
  15. package/dist/operations/modeling/predicate-applicability.d.ts.map +1 -1
  16. package/dist/operations/modeling/predicate-applicability.js +12 -3
  17. package/dist/operations/modeling/predicate-catalog-4.d.ts.map +1 -1
  18. package/dist/operations/modeling/predicate-catalog-4.js +4 -0
  19. package/dist/operations/modeling/predicate-loader.d.ts.map +1 -1
  20. package/dist/operations/modeling/predicate-loader.js +3 -0
  21. package/dist/operations/modeling/predicate-score-3.js +1 -1
  22. package/dist/operations/modeling/predicate-types.d.ts +5 -0
  23. package/dist/operations/modeling/predicate-types.d.ts.map +1 -1
  24. package/dist/operations/modeling/predicate-utils.d.ts.map +1 -1
  25. package/dist/operations/modeling/predicate-utils.js +2 -3
  26. package/dist/operations/mutation/source-authoring.d.ts +9 -0
  27. package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
  28. package/dist/operations/mutation/source-authoring.js +38 -2
  29. package/dist/operations/planning/apply-plan.d.ts.map +1 -1
  30. package/dist/operations/planning/apply-plan.js +33 -8
  31. package/dist/operations/planning/migration-refusal.d.ts +14 -0
  32. package/dist/operations/planning/migration-refusal.d.ts.map +1 -0
  33. package/dist/operations/planning/migration-refusal.js +17 -0
  34. package/dist/operations/semantic-advisor/clauses.d.ts.map +1 -1
  35. package/dist/operations/semantic-advisor/clauses.js +7 -1
  36. package/dist/operations/semantic-advisor/shared.d.ts +7 -0
  37. package/dist/operations/semantic-advisor/shared.d.ts.map +1 -1
  38. package/dist/operations/semantic-advisor/shared.js +22 -3
  39. package/dist/prolog/store-lock.d.ts +22 -0
  40. package/dist/prolog/store-lock.d.ts.map +1 -1
  41. package/dist/prolog/store-lock.js +45 -1
  42. package/dist/prolog.d.ts +7 -1
  43. package/dist/prolog.d.ts.map +1 -1
  44. package/dist/prolog.js +21 -3
  45. package/dist/proof/inspect.d.ts +9 -0
  46. package/dist/proof/inspect.d.ts.map +1 -1
  47. package/dist/proof/inspect.js +10 -0
  48. package/dist/proof/integration-plan.d.ts +2 -1
  49. package/dist/proof/integration-plan.d.ts.map +1 -1
  50. package/dist/proof/integration-plan.js +30 -13
  51. package/dist/public/impact/coverage-depth-quality.d.ts.map +1 -1
  52. package/dist/public/impact/coverage-depth-quality.js +29 -1
  53. package/dist/public/operations/contracts.d.ts.map +1 -1
  54. package/dist/public/operations/contracts.js +3 -0
  55. package/dist/public/operations/discovery-executors.d.ts +14 -1
  56. package/dist/public/operations/discovery-executors.d.ts.map +1 -1
  57. package/dist/public/operations/discovery-executors.js +62 -12
  58. package/dist/public/operations/migration-plan.d.ts +2 -0
  59. package/dist/public/operations/migration-plan.d.ts.map +1 -1
  60. package/dist/public/operations/migration-plan.js +31 -0
  61. package/dist/public/operations/result-envelope.d.ts.map +1 -1
  62. package/dist/public/operations/result-envelope.js +23 -3
  63. package/dist/public/operations/source-relationship-parity.d.ts.map +1 -1
  64. package/dist/public/operations/source-relationship-parity.js +55 -1
  65. package/dist/public/skills/kibi-usage/SKILL.md +19 -4
  66. package/dist/public/skills/kibi-usage/resources/fact-lanes.md +3 -3
  67. package/dist/public/skills/kibi-usage/resources/proof.md +44 -3
  68. package/dist/utils/branch-store.d.ts +8 -0
  69. package/dist/utils/branch-store.d.ts.map +1 -1
  70. package/dist/utils/branch-store.js +27 -1
  71. package/dist/utils/content-freshness.d.ts +13 -0
  72. package/dist/utils/content-freshness.d.ts.map +1 -0
  73. package/dist/utils/content-freshness.js +161 -0
  74. package/package.json +2 -2
  75. package/src/public/impact/coverage-depth-quality.ts +46 -1
  76. package/src/public/operations/contracts.ts +3 -0
  77. package/src/public/operations/discovery-executors.ts +89 -11
  78. package/src/public/operations/migration-plan.ts +44 -0
  79. package/src/public/operations/result-envelope.ts +31 -3
  80. package/src/public/operations/source-relationship-parity.ts +60 -3
  81. package/src/public/skills/kibi-usage/SKILL.md +19 -4
  82. package/src/public/skills/kibi-usage/resources/fact-lanes.md +3 -3
  83. package/src/public/skills/kibi-usage/resources/proof.md +44 -3
@@ -80,6 +80,15 @@ export declare function renderYamlRelationshipDeletion(sourcePathValue: string,
80
80
  * so a plan writes exactly what `kb_upsert` would.
81
81
  */
82
82
  export declare function renderSourceDocument(input: UpsertInput, entity: Readonly<Record<string, unknown>>, existingContent: string | undefined, relativePath: string): string;
83
+ /**
84
+ * Whether Git definitely does not track `relative`. Sync reads only tracked
85
+ * sources plus pending-source receipts, so an untracked file (for example the
86
+ * `.kb/symbols.yaml` that `kibi init` creates) needs a receipt on every
87
+ * write, or a new branch store compiles relationships without the entities
88
+ * they connect. Any other Git outcome (not a repository, git missing) is
89
+ * "unknown" and keeps the previous behaviour.
90
+ */
91
+ export declare function isUntrackedByGit(workspaceRoot: string, relative: string): boolean;
83
92
  export declare function writeSourceForUpsert(input: UpsertInput, entity: Readonly<Record<string, unknown>>, existing?: Readonly<Record<string, unknown>>, context?: OperationContext, sourceDocumentOverride?: string): Promise<{
84
93
  receipt: SourceWriteReceipt;
85
94
  rollback: () => Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"source-authoring.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/source-authoring.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAMjF,OAAO,KAAK,EAAqB,WAAW,EAAE,MAAM,YAAY,CAAC;AAEjE,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IACzB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC,CAAC;AAmBH,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,GAChB,IAAI,CAiBN;AAED,KAAK,SAAS,GAAG,QAAQ,CAAC;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,IAAI,CAAA;CAAE,CAAC,CAAC;AAExD,8EAA8E;AAE9E,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAOpE;AAED;;;;GAIG;AAEH,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,SAAS,GAAG,IAAI,GACtB,IAAI,CAON;AAeD;;;;GAIG;AAEH,wBAAgB,0BAA0B,CACxC,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,GACnB,IAAI,CAMN;AAgBD,wBAAgB,0BAA0B,CACxC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,MAAM,CAqCR;AAED,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,GACb,MAAM,CAoBR;AAsBD;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CAYpB;AAED,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,GACX,OAAO,CAET;AAkGD,uFAAuF;AAEvF,eAAO,MAAM,uBAAuB,uGAM1B,CAAC;AA8BX,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,OAAO,GACZ,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAiCzC;AAoRD,wBAAgB,oBAAoB,CAClC,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,GACtB;IAAE,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CA6C7C;AAED;;;;;;;GAOG;AACH,wBAAgB,kCAAkC,CAChD,eAAe,EAAE,MAAM,EACvB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,GAC7D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CA4DpC;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAC5C,eAAe,EAAE,MAAM,EACvB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC,GAC7D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAiEpC;AAED;;;;GAIG;AAEH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,eAAe,EAAE,MAAM,GAAG,SAAS,EACnC,YAAY,EAAE,MAAM,GACnB,MAAM,CAsBR;AAED,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAC5C,OAAO,CAAC,EAAE,gBAAgB,EAC1B,sBAAsB,CAAC,EAAE,MAAM,GAC9B,OAAO,CAAC;IACT,OAAO,EAAE,kBAAkB,CAAC;IAC5B,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B,GAAG,IAAI,CAAC,CA6IR;AAED,uEAAuE;AACvE,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACzC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAC3C,MAAM,CAOR"}
1
+ {"version":3,"file":"source-authoring.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/source-authoring.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { execFileSync } from "node:child_process";
1
2
  import { createHash } from "node:crypto";
2
3
  import { randomUUID } from "node:crypto";
3
4
  import fs from "node:fs";
@@ -462,7 +463,19 @@ function renderSymbolManifest(entity, relationships, existingContent) {
462
463
  if (!symbols || typeof symbols !== "object" || !("items" in symbols)) {
463
464
  throw new OperationError("SOURCE_FORMAT_INVALID", "Symbol manifest must contain a symbols array");
464
465
  }
465
- const items = symbols.items;
466
+ // implements REQ-core-persistence
467
+ // `kibi init` writes `symbols: []`, a flow sequence; appending to it kept
468
+ // every symbol on one line. Render the list (and the entries that were
469
+ // written inside it) as block YAML so diffs stay reviewable.
470
+ const sequence = symbols;
471
+ if (sequence.flow === true) {
472
+ sequence.flow = false;
473
+ for (const item of sequence.items) {
474
+ if (item && typeof item === "object" && "flow" in item)
475
+ item.flow = false;
476
+ }
477
+ }
478
+ const items = sequence.items;
466
479
  const id = String(entity.id);
467
480
  const indices = items.flatMap((item, index) => {
468
481
  if (!item || typeof item !== "object" || !("get" in item))
@@ -670,6 +683,27 @@ export function renderSourceDocument(input, entity, existingContent, relativePat
670
683
  }
671
684
  return renderEntityDocument(input, entity, existingContent);
672
685
  }
686
+ /**
687
+ * Whether Git definitely does not track `relative`. Sync reads only tracked
688
+ * sources plus pending-source receipts, so an untracked file (for example the
689
+ * `.kb/symbols.yaml` that `kibi init` creates) needs a receipt on every
690
+ * write, or a new branch store compiles relationships without the entities
691
+ * they connect. Any other Git outcome (not a repository, git missing) is
692
+ * "unknown" and keeps the previous behaviour.
693
+ */
694
+ // implements REQ-core-persistence
695
+ export function isUntrackedByGit(workspaceRoot, relative) {
696
+ try {
697
+ execFileSync("git", ["-C", workspaceRoot, "ls-files", "--error-unmatch", "--", relative],
698
+ // Bounded: a write must never wait on Git. A timeout reads as
699
+ // "tracked", the pre-receipt behaviour.
700
+ { stdio: "ignore", timeout: 10_000 });
701
+ return false;
702
+ }
703
+ catch (error) {
704
+ return error.status === 1;
705
+ }
706
+ }
673
707
  export async function writeSourceForUpsert(input, entity, existing, context, sourceDocumentOverride) {
674
708
  if (!context?.fs)
675
709
  return null;
@@ -795,7 +829,9 @@ export async function writeSourceForUpsert(input, entity, existing, context, sou
795
829
  };
796
830
  try {
797
831
  if (receipt.afterHash !== null &&
798
- (before === undefined || fs.existsSync(pendingReceipt))) {
832
+ (before === undefined ||
833
+ fs.existsSync(pendingReceipt) ||
834
+ isUntrackedByGit(context.workspaceRoot, relative))) {
799
835
  writePendingSourceReceipt(context.workspaceRoot, relative, receipt.afterHash);
800
836
  }
801
837
  }
@@ -1 +1 @@
1
- {"version":3,"file":"apply-plan.d.ts","sourceRoot":"","sources":["../../../src/operations/planning/apply-plan.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAEV,gBAAgB,EAGjB,MAAM,0CAA0C,CAAC;AASlD,OAAO,EACL,KAAK,eAAe,EAIrB,MAAM,uBAAuB,CAAC;AA+D/B,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EAGhB,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,aAAa,EACb,eAAe,EACf,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAG/B,eAAO,MAAM,yBAAyB,EAAG,2BAAoC,CAAC;AA6G9E,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,IAAI,CAMN;AAED,wBAAgB,mCAAmC,CACjD,SAAS,EAAE,SAAS;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,EAAE,EACnE,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,GAC3B,IAAI,CAaN;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,SAAS,eAAe,EAAE,EACnC,SAAS,cAAoB,GAC5B,eAAe,EAAE,CA2CnB;AA8zBD;;;;;;GAMG;AAEH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,IAAI,CAAC,CAiCf;AAyqDD,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC;IACT,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,iBAAiB,EAAE,eAAe,CAAC;CACpC,CAAC,CAkDD"}
1
+ {"version":3,"file":"apply-plan.d.ts","sourceRoot":"","sources":["../../../src/operations/planning/apply-plan.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAEV,gBAAgB,EAGjB,MAAM,0CAA0C,CAAC;AASlD,OAAO,EACL,KAAK,eAAe,EAIrB,MAAM,uBAAuB,CAAC;AAgE/B,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EAGhB,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EACV,aAAa,EACb,eAAe,EACf,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAG/B,eAAO,MAAM,yBAAyB,EAAG,2BAAoC,CAAC;AA6G9E,wBAAgB,iCAAiC,CAC/C,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GAChB,IAAI,CAMN;AAED,wBAAgB,mCAAmC,CACjD,SAAS,EAAE,SAAS;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,EAAE,EACnE,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,GAC3B,IAAI,CAaN;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,SAAS,eAAe,EAAE,EACnC,SAAS,cAAoB,GAC5B,eAAe,EAAE,CA2CnB;AA8zBD;;;;;;GAMG;AAEH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,IAAI,CAAC,CAiCf;AAyqDD,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC;IACT,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,iBAAiB,EAAE,eAAe,CAAC;CACpC,CAAC,CAkDD"}
@@ -7,7 +7,7 @@ import { syncCommand } from "../../commands/sync.js";
7
7
  import { PROOF_INTEGRATION_CONFIGURE, applyProofIntegrationAction, } from "../../proof/integration-plan.js";
8
8
  import { loadEntities } from "../../public/operations/discovery-entities.js";
9
9
  import { executeStatus } from "../../public/operations/discovery-executors.js";
10
- import { PREDICATE_SCHEMA_ALIGNMENT_CODE, migrationPlanHash, } from "../../public/operations/migration-plan.js";
10
+ import { FRESHNESS_RESYNC, PREDICATE_SCHEMA_ALIGNMENT_CODE, migrationPlanHash, } from "../../public/operations/migration-plan.js";
11
11
  import { readMigrationConfigStatus } from "../../public/operations/migration-plan.js";
12
12
  import { readWorkspaceSnapshot } from "../../public/operations/workspace-snapshot.js";
13
13
  import { computeShardPath, renderShardWithRelationship, } from "../../relationships/shards.js";
@@ -24,6 +24,7 @@ import { canonicalSourcePath, renderSourceDocument, } from "../mutation/source-a
24
24
  import { assertRelationshipShardContained, executeUpsert, validateUpsertForCommit, } from "../mutation/upsert.js";
25
25
  import { acquireWorkspaceMutationLock, releaseWorkspaceMutationLock, } from "../mutation/workspace-mutation-lock.js";
26
26
  import { compilePlanHash, isBlockingWitness, parseWhatIfAnalysis, planWhatIfGoal, } from "./compile-intent.js";
27
+ import { MigrationActionRefusedError } from "./migration-refusal.js";
27
28
  // implements REQ-kibi-change-to-proof-plan-compiler-v2
28
29
  export const PLAN_APPLY_RESULT_VERSION = "kibi.plan-apply-result.v1";
29
30
  const ENTITY_TYPES = new Set([
@@ -2121,6 +2122,9 @@ async function applyMigrationPlan(args, context, onCommitted = () => undefined)
2121
2122
  }
2122
2123
  const results = [];
2123
2124
  let failed = false;
2125
+ // Failures that changed nothing (a precondition refused the action).
2126
+ let refusals = 0;
2127
+ let failures = 0;
2124
2128
  for (const action of actions) {
2125
2129
  if (failed) {
2126
2130
  results.push({
@@ -2141,6 +2145,9 @@ async function applyMigrationPlan(args, context, onCommitted = () => undefined)
2141
2145
  }
2142
2146
  catch (error) {
2143
2147
  failed = true;
2148
+ failures += 1;
2149
+ if (error instanceof MigrationActionRefusedError)
2150
+ refusals += 1;
2144
2151
  results.push({
2145
2152
  actionId: action.id,
2146
2153
  outcome: "failed",
@@ -2190,10 +2197,15 @@ async function applyMigrationPlan(args, context, onCommitted = () => undefined)
2190
2197
  });
2191
2198
  }
2192
2199
  }
2200
+ // refused: nothing was applied and every failure was a refusal, so the
2201
+ // workspace is as it was; reconciliation_required: an action failed
2202
+ // without being refused, so its effect must be inspected.
2193
2203
  const outcome = failed
2194
2204
  ? results.some((result) => result.outcome === "applied")
2195
2205
  ? "partially_applied"
2196
- : "reconciliation_required"
2206
+ : failures > 0 && refusals === failures
2207
+ ? "refused"
2208
+ : "reconciliation_required"
2197
2209
  : "applied";
2198
2210
  const kbState = finalStatus.branchAttachment?.migrationRequired
2199
2211
  ? "legacy_compat"
@@ -2237,7 +2249,7 @@ async function applyMigrationPlan(args, context, onCommitted = () => undefined)
2237
2249
  closeout: {
2238
2250
  taskOutcome: outcome === "applied"
2239
2251
  ? "complete"
2240
- : outcome === "reconciliation_required"
2252
+ : outcome === "reconciliation_required" || outcome === "refused"
2241
2253
  ? "blocked"
2242
2254
  : "interim",
2243
2255
  kbState,
@@ -2250,7 +2262,11 @@ async function applyMigrationPlan(args, context, onCommitted = () => undefined)
2250
2262
  content: [
2251
2263
  {
2252
2264
  type: "text",
2253
- text: `${outcome === "applied" ? "Applied" : "Stopped after"} migration plan ${args.plan.planHash.slice(0, 12)}.`,
2265
+ text: outcome === "applied"
2266
+ ? `Applied migration plan ${args.plan.planHash.slice(0, 12)}.`
2267
+ : outcome === "refused"
2268
+ ? `Refused migration plan ${args.plan.planHash.slice(0, 12)}; nothing was changed.`
2269
+ : `Stopped after migration plan ${args.plan.planHash.slice(0, 12)}.`,
2254
2270
  },
2255
2271
  ],
2256
2272
  structuredContent: payload,
@@ -2289,6 +2305,15 @@ async function applyMigrationAction(action, context) {
2289
2305
  throw new Error("Compiling the branch store (kibi sync) did not complete successfully.");
2290
2306
  return;
2291
2307
  }
2308
+ // implements REQ-cli-status-pre-first-sync
2309
+ case FRESHNESS_RESYNC: {
2310
+ const result = await syncCommand({
2311
+ workspaceRoot: context.workspaceRoot,
2312
+ });
2313
+ if (!result.success)
2314
+ throw new Error("Recompiling changed sources (kibi sync) did not complete successfully.");
2315
+ return;
2316
+ }
2292
2317
  case "damaged_exact_branch_store":
2293
2318
  await branchRecoverCommand({
2294
2319
  apply: true,
@@ -2327,7 +2352,7 @@ async function applyMigrationAction(action, context) {
2327
2352
  await applySchema6MigrationAction(action, context);
2328
2353
  return;
2329
2354
  }
2330
- throw new Error(`Migration action '${action.code}' has no automatic executor.`);
2355
+ throw new MigrationActionRefusedError(`Migration action '${action.code}' has no automatic executor.`);
2331
2356
  }
2332
2357
  }
2333
2358
  /**
@@ -2338,10 +2363,10 @@ async function applyMigrationAction(action, context) {
2338
2363
  async function applyPredicateSchemaAlignment(action, context) {
2339
2364
  const invocation = action.invocation;
2340
2365
  if (invocation.kind !== "operation" || invocation.name !== "kb_upsert")
2341
- throw new Error("Predicate schema alignment requires its planned kb_upsert invocation.");
2366
+ throw new MigrationActionRefusedError("Predicate schema alignment requires its planned kb_upsert invocation.");
2342
2367
  const input = asUpsert(invocation.input);
2343
2368
  if (input.type !== "fact")
2344
- throw new Error("Predicate schema alignment only rewrites fact entities.");
2369
+ throw new MigrationActionRefusedError("Predicate schema alignment only rewrites fact entities.");
2345
2370
  const prolog = context.prolog ?? (await context.ensureProlog?.());
2346
2371
  if (!prolog)
2347
2372
  throw new Error("Predicate schema alignment requires a Prolog runtime.");
@@ -2363,6 +2388,6 @@ async function applyPredicateSchemaAlignment(action, context) {
2363
2388
  typeof rewrite.index === "number" &&
2364
2389
  currentArgs[rewrite.index] === rewrite.from);
2365
2390
  if (!unchanged)
2366
- throw new Error(`Predicate fact ${input.id} changed since planning; rerun kibi check and approve the new plan.`);
2391
+ throw new MigrationActionRefusedError(`Predicate fact ${input.id} changed since planning; rerun kibi check and approve the new plan.`);
2367
2392
  await executeUpsert(input, operationContext);
2368
2393
  }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * A migration action executor throws this when it refuses to run: a
3
+ * precondition failed before it changed anything (the planned file already
4
+ * exists, a source changed since planning, the action is malformed). An
5
+ * application whose only failures are refusals and that applied nothing
6
+ * reports `outcome: "refused"`, not `reconciliation_required`: there is
7
+ * nothing to reconcile.
8
+ */
9
+ export declare class MigrationActionRefusedError extends Error {
10
+ constructor(message: string);
11
+ }
12
+ /** Error code of the envelope for a migration plan that was refused. */
13
+ export declare const MIGRATION_PLAN_REFUSED: "MIGRATION_PLAN_REFUSED";
14
+ //# sourceMappingURL=migration-refusal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migration-refusal.d.ts","sourceRoot":"","sources":["../../../src/operations/planning/migration-refusal.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,qBAAa,2BAA4B,SAAQ,KAAK;gBACxC,OAAO,EAAE,MAAM;CAI5B;AAED,wEAAwE;AACxE,eAAO,MAAM,sBAAsB,EAAG,wBAAiC,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * A migration action executor throws this when it refuses to run: a
3
+ * precondition failed before it changed anything (the planned file already
4
+ * exists, a source changed since planning, the action is malformed). An
5
+ * application whose only failures are refusals and that applied nothing
6
+ * reports `outcome: "refused"`, not `reconciliation_required`: there is
7
+ * nothing to reconcile.
8
+ */
9
+ // implements REQ-kibi-change-to-proof-plan-compiler-v2
10
+ export class MigrationActionRefusedError extends Error {
11
+ constructor(message) {
12
+ super(message);
13
+ this.name = "MigrationActionRefusedError";
14
+ }
15
+ }
16
+ /** Error code of the envelope for a migration plan that was refused. */
17
+ export const MIGRATION_PLAN_REFUSED = "MIGRATION_PLAN_REFUSED";
@@ -1 +1 @@
1
- {"version":3,"file":"clauses.d.ts","sourceRoot":"","sources":["../../../src/operations/semantic-advisor/clauses.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,UAAU,GAAG,UAAU,CAAC;CACjC,CAAC,CAAC;AAYH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D;AAQD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,GAChB,WAAW,GAAG,aAAa,CAG7B;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAW7D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIrD;AA4BD,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,GAClC,SAAS,cAAc,EAAE,CA4B3B"}
1
+ {"version":3,"file":"clauses.d.ts","sourceRoot":"","sources":["../../../src/operations/semantic-advisor/clauses.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,UAAU,GAAG,UAAU,CAAC;CACjC,CAAC,CAAC;AAkBH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE3D;AAQD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,GAChB,WAAW,GAAG,aAAa,CAG7B;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAW7D;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIrD;AA4BD,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,GAClC,SAAS,cAAc,EAAE,CA4B3B"}
@@ -1,5 +1,11 @@
1
1
  import { createHash } from "node:crypto";
2
- const NORMATIVE_ASSERTION_PATTERN = /\b(?:must|shall|should|required|requires?|may\s+only|may\s+(?:not\s+)?(?:be\s+)?\w+\s+only\b|may\s+(?:have\s+)?(?:at\s+most|at\s+least|exactly|no\s+more\s+than|up\s+to)|only\s+.+?\s+(?:may|can)|must\s+not|shall\s+not|cannot|can't|denied|forbidden|prohibited|(?:is|are|be|become|becomes|remain|remains)\s+(?:invalid|rejected|prohibited|forbidden)|(?:reject|rejects|rejected|rejection)\s+(?:invalid|unresolved|ambiguous)|fail(?:s|ed)?\s+(?:clearly|explicitly|with)|expires?\s+(?:after|within|in)|failure\s+(?:behavior|policy|outcome)|error\s+(?:handling|behavior|policy|outcome)|required\s+outcome|defaults?\s+to)\b/i;
2
+ // An explicit grant ("are allowed to", "is permitted to") asserts a
3
+ // permission just as "denied"/"forbidden" assert a prohibition. Bare "can" and
4
+ // "may" are accepted by the predicate applicability gate but not here: stored
5
+ // clause roles are derived from this pattern, and "it can be restricted to …"
6
+ // style capability prose would turn existing descriptive inventories into
7
+ // unmodeled normative clauses.
8
+ const NORMATIVE_ASSERTION_PATTERN = /\b(?:must|shall|should|required|requires?|may\s+only|(?:is|are)\s+(?:not\s+)?(?:allowed|permitted)\s+to|permitted|may\s+(?:not\s+)?(?:be\s+)?\w+\s+only\b|may\s+(?:have\s+)?(?:at\s+most|at\s+least|exactly|no\s+more\s+than|up\s+to)|only\s+.+?\s+(?:may|can)|must\s+not|shall\s+not|cannot|can't|denied|forbidden|prohibited|(?:is|are|be|become|becomes|remain|remains)\s+(?:invalid|rejected|prohibited|forbidden)|(?:reject|rejects|rejected|rejection)\s+(?:invalid|unresolved|ambiguous)|fail(?:s|ed)?\s+(?:clearly|explicitly|with)|expires?\s+(?:after|within|in)|failure\s+(?:behavior|policy|outcome)|error\s+(?:handling|behavior|policy|outcome)|required\s+outcome|defaults?\s+to)\b/i;
3
9
  // Conditional/temporal cues help discover clauses but do not by themselves
4
10
  // turn explanatory or subjective context into an asserted obligation.
5
11
  const NORMATIVE_PATTERN = new RegExp(`${NORMATIVE_ASSERTION_PATTERN.source}|\\b(?:before|unless|when|if)\\b`, "i");
@@ -19,6 +19,13 @@ export declare function statementOf(payload: Payload): string;
19
19
  export declare function sourceOf(payload: Payload): string;
20
20
  export declare function normalizeKey(value: string): string;
21
21
  export declare function normalizePredicateToken(value: string): string;
22
+ /**
23
+ * Singularize one lowercase key token: `-ches`/`-shes`/`-sses`/`-xes` drop
24
+ * "es", `-ies` becomes "y", and any other trailing "s" is dropped unless the
25
+ * token ends in "ss", "us" or "is" ("access", "status", "analysis"). Tokens of
26
+ * three letters or fewer and the `keep` exceptions are returned unchanged.
27
+ */
28
+ export declare function singularizeToken(value: string, keep?: readonly string[]): string;
22
29
  export declare function singularize(value: string): string;
23
30
  export declare function normalizeSubjectKey(value: string): string;
24
31
  export declare function relationship(from: string, to: string, type: string): Record<string, unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/operations/semantic-advisor/shared.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,0BAA0B,EAE1B,2BAA2B,EAC5B,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AACxD,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;AACvE,eAAO,MAAM,0BAA0B,+BAA+B,CAAC;AACvE,MAAM,MAAM,mBAAmB,GAAG,eAAe,GAAG,UAAU,GAAG,OAAO,CAAC;AAGzE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE;AAGD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAElD;AAGD,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CASnD;AAGD,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAKpD;AAGD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG;IAClD,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAmBA;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,OAAO,GACf,SAAS,MAAM,EAAE,GAAG,SAAS,CAO/B;AAGD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAGD,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEtE;AAGD,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAEpD;AAGD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAIjD;AAGD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOlD;AAGD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQ7D;AAGD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGjD;AAGD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,GACX,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzB;AAGD,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,2BAA2B,EAClC,SAAS,EAAE,MAAM,EACjB,UAAU,SAAM,GACf,0BAA0B,CA0F5B;AAGD,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,SAAS,EAAE,MAAM,EACjB,QAAQ,GAAE,QAAQ,GAAG,MAAiB,GACrC,0BAA0B,CA+C5B"}
1
+ {"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../../src/operations/semantic-advisor/shared.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,0BAA0B,EAE1B,2BAA2B,EAC5B,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AACxD,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;AACvE,eAAO,MAAM,0BAA0B,+BAA+B,CAAC;AACvE,MAAM,MAAM,mBAAmB,GAAG,eAAe,GAAG,UAAU,GAAG,OAAO,CAAC;AAGzE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE;AAGD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAElD;AAGD,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CASnD;AAGD,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAKpD;AAGD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG;IAClD,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB,CAmBA;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,OAAO,GACf,SAAS,MAAM,EAAE,GAAG,SAAS,CAO/B;AAGD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE/C;AAGD,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEtE;AAGD,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAEpD;AAGD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAIjD;AAGD,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAOlD;AAGD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQ7D;AAID;;;;;GAKG;AAEH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,SAAS,MAAM,EAAO,GAC3B,MAAM,CAUR;AAGD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEjD;AAGD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,GACX,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzB;AAGD,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,2BAA2B,EAClC,SAAS,EAAE,MAAM,EACjB,UAAU,SAAM,GACf,0BAA0B,CA0F5B;AAGD,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,SAAS,EAAE,MAAM,EACjB,QAAQ,GAAE,QAAQ,GAAG,MAAiB,GACrC,0BAA0B,CA+C5B"}
@@ -90,11 +90,30 @@ export function normalizePredicateToken(value) {
90
90
  .replace(/[^A-Za-z0-9_-]+/g, "_")
91
91
  .replace(/^_+|_+$/g, "");
92
92
  }
93
+ const ES_PLURAL_SUFFIXES = ["ches", "shes", "sses", "xes"];
94
+ /**
95
+ * Singularize one lowercase key token: `-ches`/`-shes`/`-sses`/`-xes` drop
96
+ * "es", `-ies` becomes "y", and any other trailing "s" is dropped unless the
97
+ * token ends in "ss", "us" or "is" ("access", "status", "analysis"). Tokens of
98
+ * three letters or fewer and the `keep` exceptions are returned unchanged.
99
+ */
93
100
  // implements REQ-mcp-semantic-advisor-preflight
94
- export function singularize(value) {
95
- if (["status", "results"].includes(value))
101
+ export function singularizeToken(value, keep = []) {
102
+ if (value.length <= 3 || keep.includes(value))
103
+ return value;
104
+ if (value.endsWith("ies") && value.length > 4) {
105
+ return `${value.slice(0, -3)}y`;
106
+ }
107
+ if (ES_PLURAL_SUFFIXES.some((suffix) => value.endsWith(suffix))) {
108
+ return value.slice(0, -2);
109
+ }
110
+ if (!value.endsWith("s") || /(?:ss|us|is)$/.test(value))
96
111
  return value;
97
- return value.endsWith("s") && value.length > 3 ? value.slice(0, -1) : value;
112
+ return value.slice(0, -1);
113
+ }
114
+ // implements REQ-mcp-semantic-advisor-preflight
115
+ export function singularize(value) {
116
+ return singularizeToken(value, ["status", "results"]);
98
117
  }
99
118
  // implements REQ-mcp-semantic-advisor-preflight
100
119
  export function normalizeSubjectKey(value) {
@@ -21,6 +21,28 @@ export declare function readStoreLockOwner(storePath: string): {
21
21
  * lives at the branch-store root (older builds kept it beside the lock).
22
22
  */
23
23
  export declare function breakStoreLock(rdfDirectory: string): void;
24
+ /** Store-root record of the last stale-lock takeover (see below). */
25
+ export declare const STORE_LOCK_TAKEOVER_FILE = ".kibi-lock-takeover.json";
26
+ /**
27
+ * How long a takeover stays visible in kb_status and kibi doctor. A takeover
28
+ * happens inside a detached engine whose output nobody reads, so the record
29
+ * outlives that engine (which may idle out within minutes) long enough to be
30
+ * seen on the next working session; the next takeover replaces it.
31
+ */
32
+ export declare const STORE_LOCK_TAKEOVER_VISIBLE_MS: number;
33
+ export type StoreLockTakeoverRecord = Readonly<{
34
+ brokenPid: number | null;
35
+ reason: string;
36
+ at: string;
37
+ path: string;
38
+ }>;
39
+ /**
40
+ * Record that a stale branch-store lock is about to be broken. Best effort:
41
+ * the record is diagnostic and must never block the takeover itself.
42
+ */
43
+ export declare function recordStoreLockTakeover(storePath: string, brokenPid: number | null, reason: string, at?: Date): void;
44
+ /** The last takeover record of a branch store, or null when none is readable. */
45
+ export declare function readStoreLockTakeover(storePath: string): StoreLockTakeoverRecord | null;
24
46
  export interface StoreLockTakeoverDecision {
25
47
  readonly action: "break" | "surface";
26
48
  readonly reason: string;
@@ -1 +1 @@
1
- {"version":3,"file":"store-lock.d.ts","sourceRoot":"","sources":["../../src/prolog/store-lock.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,KAAK,EAAqB,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAgBhF,8EAA8E;AAC9E,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAa7C;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAUnD;AAED,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAEzE,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,oBAAoB,GAAG,IAAI,GACjC,oBAAoB,CAYtB;AAED;;;;;GAKG;AAEH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,GAChB;IAAE,KAAK,EAAE,oBAAoB,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA4B7D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAWzD;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,oBAAoB,GAAG,IAAI,GACjC,yBAAyB,CAoB3B;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;CACxD;AAED;;;;;;GAMG;AAEH,wBAAsB,iCAAiC,CACrD,MAAM,EAAE,qBAAqB,EAC7B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,WAAW,CAAC,CA4BtB"}
1
+ {"version":3,"file":"store-lock.d.ts","sourceRoot":"","sources":["../../src/prolog/store-lock.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,KAAK,EAAqB,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAgBhF,8EAA8E;AAC9E,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAa7C;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAUnD;AAED,MAAM,MAAM,oBAAoB,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;AAEzE,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,oBAAoB,GAAG,IAAI,GACjC,oBAAoB,CAYtB;AAED;;;;;GAKG;AAEH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,GAChB;IAAE,KAAK,EAAE,oBAAoB,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CA4B7D;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAWzD;AAED,qEAAqE;AACrE,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AAEnE;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,QAAsB,CAAC;AAElE,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd,CAAC,CAAC;AAEH;;;GAGG;AAEH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAAG,IAAI,EACxB,MAAM,EAAE,MAAM,EACd,EAAE,GAAE,IAAiB,GACpB,IAAI,CAUN;AAED,iFAAiF;AAEjF,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,GAChB,uBAAuB,GAAG,IAAI,CAmBhC;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,oBAAoB,GAAG,IAAI,GACjC,yBAAyB,CAoB3B;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;CACxD;AAED;;;;;;GAMG;AAEH,wBAAsB,iCAAiC,CACrD,MAAM,EAAE,qBAAqB,EAC7B,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,WAAW,CAAC,CAiCtB"}
@@ -15,7 +15,7 @@
15
15
  You should have received a copy of the GNU Affero General Public License
16
16
  along with this program. If not, see <https://www.gnu.org/licenses/>.
17
17
  */
18
- import { existsSync, rmSync } from "node:fs";
18
+ import { existsSync, rmSync, writeFileSync } from "node:fs";
19
19
  import { readFileSync } from "node:fs";
20
20
  import { dirname, join } from "node:path";
21
21
  import { escapeAtom } from "./codec.js";
@@ -133,6 +133,49 @@ export function breakStoreLock(rdfDirectory) {
133
133
  }
134
134
  }
135
135
  }
136
+ /** Store-root record of the last stale-lock takeover (see below). */
137
+ export const STORE_LOCK_TAKEOVER_FILE = ".kibi-lock-takeover.json";
138
+ /**
139
+ * How long a takeover stays visible in kb_status and kibi doctor. A takeover
140
+ * happens inside a detached engine whose output nobody reads, so the record
141
+ * outlives that engine (which may idle out within minutes) long enough to be
142
+ * seen on the next working session; the next takeover replaces it.
143
+ */
144
+ export const STORE_LOCK_TAKEOVER_VISIBLE_MS = 24 * 60 * 60 * 1000;
145
+ /**
146
+ * Record that a stale branch-store lock is about to be broken. Best effort:
147
+ * the record is diagnostic and must never block the takeover itself.
148
+ */
149
+ // implements REQ-core-journaled-engine-persistence
150
+ export function recordStoreLockTakeover(storePath, brokenPid, reason, at = new Date()) {
151
+ try {
152
+ writeFileSync(join(storePath, STORE_LOCK_TAKEOVER_FILE), `${JSON.stringify({ brokenPid, reason, at: at.toISOString() })}\n`, { mode: 0o600 });
153
+ }
154
+ catch {
155
+ // A read-only or vanished store still gets its lock broken.
156
+ }
157
+ }
158
+ /** The last takeover record of a branch store, or null when none is readable. */
159
+ // implements REQ-core-journaled-engine-persistence
160
+ export function readStoreLockTakeover(storePath) {
161
+ const recordPath = join(storePath, STORE_LOCK_TAKEOVER_FILE);
162
+ if (!existsSync(recordPath))
163
+ return null;
164
+ try {
165
+ const parsed = JSON.parse(readFileSync(recordPath, "utf8"));
166
+ if (typeof parsed.at !== "string" || Number.isNaN(Date.parse(parsed.at)))
167
+ return null;
168
+ return {
169
+ brokenPid: typeof parsed.brokenPid === "number" ? parsed.brokenPid : null,
170
+ reason: typeof parsed.reason === "string" ? parsed.reason : "",
171
+ at: parsed.at,
172
+ path: recordPath,
173
+ };
174
+ }
175
+ catch {
176
+ return null;
177
+ }
178
+ }
136
179
  /**
137
180
  * Decide whether a store-locked failure may be auto-healed. Only a provably
138
181
  * dead holder (or a holder from a previous boot) is broken; live or unknown
@@ -186,6 +229,7 @@ Store lock holder: ${holderSummary}. Close that session, or run 'kibi engine sto
186
229
  const lockDirectory = storeLocked.lockDirectory !== ""
187
230
  ? storeLocked.lockDirectory
188
231
  : join(kbPath, "rdf");
232
+ recordStoreLockTakeover(kbPath, storeLocked.owner?.pid ?? null, decision.reason);
189
233
  breakStoreLock(lockDirectory);
190
234
  const retried = await prolog.query(`kb_attach('${escapeAtom(kbPath)}')`);
191
235
  if (retried.success) {
package/dist/prolog.d.ts CHANGED
@@ -122,6 +122,12 @@ export declare class PrologProcess {
122
122
  isRunning(): boolean;
123
123
  getPid(): number;
124
124
  private lostProcessError;
125
- terminate(): Promise<void>;
125
+ /**
126
+ * Stop the Prolog child. `graceMs` lets the interactive toplevel halt on
127
+ * stdin EOF (running its at_halt hooks) before it is signalled.
128
+ */
129
+ terminate(options?: {
130
+ graceMs?: number;
131
+ }): Promise<void>;
126
132
  }
127
133
  //# sourceMappingURL=prolog.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prolog.d.ts","sourceRoot":"","sources":["../src/prolog.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prolog.d.ts","sourceRoot":"","sources":["../src/prolog.ts"],"names":[],"mappings":"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"}
package/dist/prolog.js CHANGED
@@ -826,7 +826,7 @@ export class PrologProcess {
826
826
  // The child may have exited between the group and direct kill attempts.
827
827
  }
828
828
  }
829
- async terminateProcessTree(child) {
829
+ async terminateProcessTree(child, graceMs = 0) {
830
830
  let closed = false;
831
831
  const exited = new Promise((resolve) => {
832
832
  const markExited = () => {
@@ -836,6 +836,20 @@ export class PrologProcess {
836
836
  child.once("close", markExited);
837
837
  child.once("error", markExited);
838
838
  });
839
+ if (graceMs > 0 && child.exitCode === null && child.signalCode === null) {
840
+ // implements REQ-core-journaled-engine-persistence
841
+ let graceTimer;
842
+ await Promise.race([
843
+ exited,
844
+ new Promise((resolve) => {
845
+ graceTimer = setTimeout(resolve, graceMs);
846
+ }),
847
+ ]);
848
+ if (graceTimer)
849
+ clearTimeout(graceTimer);
850
+ if (closed)
851
+ return;
852
+ }
839
853
  if (child.exitCode === null)
840
854
  this.signalProcessTree(child, "SIGTERM");
841
855
  await Promise.race([
@@ -992,7 +1006,11 @@ export class PrologProcess {
992
1006
  }
993
1007
  return new PrologProcessTerminatedError(this.terminationReason ?? "process exited");
994
1008
  }
995
- async terminate() {
1009
+ /**
1010
+ * Stop the Prolog child. `graceMs` lets the interactive toplevel halt on
1011
+ * stdin EOF (running its at_halt hooks) before it is signalled.
1012
+ */
1013
+ async terminate(options = {}) {
996
1014
  if (this.interactiveStarted) {
997
1015
  this.terminationReason ??= "terminated";
998
1016
  }
@@ -1012,7 +1030,7 @@ export class PrologProcess {
1012
1030
  this.terminationPromise = (async () => {
1013
1031
  if (current) {
1014
1032
  current.stdin?.end();
1015
- await this.terminateProcessTree(current);
1033
+ await this.terminateProcessTree(current, options.graceMs ?? 0);
1016
1034
  }
1017
1035
  await Promise.all(oneShots.map((child) => this.terminateProcessTree(child)));
1018
1036
  })();
@@ -5,7 +5,14 @@ export type ProofInspection = Readonly<{
5
5
  buildSystems: readonly string[];
6
6
  detectedRunners: readonly string[];
7
7
  ciWorkflows: readonly string[];
8
+ /** Comma-joined ids of the configured integrations (kept for compatibility). */
8
9
  currentIntegration: string | null;
10
+ /** Each configured integration with the producer and command it runs. */
11
+ currentIntegrations: readonly Readonly<{
12
+ id: string;
13
+ producer: string;
14
+ command: readonly string[];
15
+ }>[];
9
16
  recommendation: string;
10
17
  missing: readonly string[];
11
18
  /** The integration Kibi proposes for the detected runner, if any. */
@@ -23,6 +30,8 @@ export type ProofInspection = Readonly<{
23
30
  export type ProofInspectionOptions = Readonly<{
24
31
  /** Plan a replacement of this existing integration id. */
25
32
  update?: string;
33
+ /** Command (argv) the proposed integration runs instead of the detected one. */
34
+ command?: readonly string[];
26
35
  }>;
27
36
  export declare function directoryEntriesMatch(directory: string, regex: RegExp): boolean;
28
37
  export declare function inspectProofEnvironment(root: string, options?: ProofInspectionOptions): ProofInspection;
@@ -1 +1 @@
1
- {"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../../src/proof/inspect.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EACL,KAAK,mBAAmB,EAEzB,MAAM,uBAAuB,CAAC;AAM/B,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,qEAAqE;IACrE,mBAAmB,EAAE,mBAAmB,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;IAC/D,6EAA6E;IAC7E,gBAAgB,EAAE,mBAAmB,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC;IACjE;;;OAGG;IACH,eAAe,EAAE,aAAa,GAAG,IAAI,CAAC;IACtC,sDAAsD;IACtD,qBAAqB,EAAE,MAAM,CAAC;CAC/B,CAAC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAC5C,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAwIH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAMT;AA2BD,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,sBAA2B,GACnC,eAAe,CAgGjB"}
1
+ {"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../../src/proof/inspect.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EACL,KAAK,mBAAmB,EAEzB,MAAM,uBAAuB,CAAC;AAM/B,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IAC7B,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,gFAAgF;IAChF,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,yEAAyE;IACzE,mBAAmB,EAAE,SAAS,QAAQ,CAAC;QACrC,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;KAC5B,CAAC,EAAE,CAAC;IACL,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,qEAAqE;IACrE,mBAAmB,EAAE,mBAAmB,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC;IAC/D,6EAA6E;IAC7E,gBAAgB,EAAE,mBAAmB,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC;IACjE;;;OAGG;IACH,eAAe,EAAE,aAAa,GAAG,IAAI,CAAC;IACtC,sDAAsD;IACtD,qBAAqB,EAAE,MAAM,CAAC;CAC/B,CAAC,CAAC;AAEH,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAC5C,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7B,CAAC,CAAC;AAwIH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAMT;AA2BD,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,sBAA2B,GACnC,eAAe,CA0GjB"}
@@ -208,6 +208,15 @@ export function inspectProofEnvironment(root, options = {}) {
208
208
  const currentIntegration = integrations.available
209
209
  ? integrations.integrations.integrations.map((entry) => entry.id).join(", ")
210
210
  : null;
211
+ // implements REQ-kibi-verification-evidence-contract
212
+ // The id alone does not say what `kibi prove` will run; expose the command.
213
+ const currentIntegrations = integrations.available
214
+ ? integrations.integrations.integrations.map((entry) => ({
215
+ id: entry.id,
216
+ producer: entry.producer,
217
+ command: [...entry.command],
218
+ }))
219
+ : [];
211
220
  const planned = buildProofIntegrationPlan(root, options);
212
221
  const applyHint = "review integrationPlan, then apply it with kb_apply_plan (or `kibi apply-plan --input -`) passing plan, approvedPlanHash = plan.planHash and approvedActionIds";
213
222
  let recommendation;
@@ -235,6 +244,7 @@ export function inspectProofEnvironment(root, options = {}) {
235
244
  detectedRunners: runners,
236
245
  ciWorkflows,
237
246
  currentIntegration,
247
+ currentIntegrations,
238
248
  recommendation,
239
249
  missing,
240
250
  proposedIntegration: planned.proposal?.integration ?? null,
@@ -33,7 +33,7 @@ export type ProofIntegrationPlanResult = Readonly<{
33
33
  * (aggregate-run provenance), so it works for every runner without a
34
34
  * reporter; a native producer can replace it later through an update plan.
35
35
  */
36
- export declare function proposeProofIntegration(root: string, overrideId?: string): ProposedIntegration | null;
36
+ export declare function proposeProofIntegration(root: string, overrideId?: string, overrideCommand?: readonly string[]): ProposedIntegration | null;
37
37
  /**
38
38
  * Build the hash-bound `kibi.migration-plan.v2` that writes
39
39
  * `.kb/proof/integrations.json` through Kibi. Without `update`, a plan is
@@ -44,6 +44,7 @@ export declare function proposeProofIntegration(root: string, overrideId?: strin
44
44
  */
45
45
  export declare function buildProofIntegrationPlan(root: string, options?: Readonly<{
46
46
  update?: string;
47
+ command?: readonly string[];
47
48
  }>): ProofIntegrationPlanResult;
48
49
  /**
49
50
  * Apply one reviewed `proof_integration_configure` action: write
@@ -1 +1 @@
1
- {"version":3,"file":"integration-plan.d.ts","sourceRoot":"","sources":["../../src/proof/integration-plan.ts"],"names":[],"mappings":"AAUA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,aAAa,EAGnB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,sBAAsB,EAEvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAEL,KAAK,gBAAgB,EAGtB,MAAM,mBAAmB,CAAC;AAE3B,mEAAmE;AACnE,eAAO,MAAM,2BAA2B,gCAAgC,CAAC;AAqCzE,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,WAAW,EAAE,gBAAgB,CAAC;IAC9B,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,gBAAgB,EAAE,QAAQ,CAAC;QACzB,OAAO,EAAE,OAAO,sBAAsB,CAAC;QACvC,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,aAAa,CAAC;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACtE,cAAc,EAAE,4BAA4B,CAAC;KAC9C,CAAC,CAAC;CACJ,CAAC,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAAC;IAChD,0EAA0E;IAC1E,IAAI,EAAE,aAAa,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACrC,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAyGH;;;;;;;GAOG;AAEH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,GAClB,mBAAmB,GAAG,IAAI,CA8B5B;AAsCD;;;;;;;GAOG;AAEH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,QAAQ,CAAC;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAM,GAC1C,0BAA0B,CAiE5B;AAMD;;;;;;;GAOG;AAEH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,MAAM,GACX,IAAI,CAyDN"}
1
+ {"version":3,"file":"integration-plan.d.ts","sourceRoot":"","sources":["../../src/proof/integration-plan.ts"],"names":[],"mappings":"AAWA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,aAAa,EAGnB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,sBAAsB,EAEvB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAEL,KAAK,gBAAgB,EAGtB,MAAM,mBAAmB,CAAC;AAE3B,mEAAmE;AACnE,eAAO,MAAM,2BAA2B,gCAAgC,CAAC;AAqCzE,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,WAAW,EAAE,gBAAgB,CAAC;IAC9B,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,6EAA6E;IAC7E,gBAAgB,EAAE,QAAQ,CAAC;QACzB,OAAO,EAAE,OAAO,sBAAsB,CAAC;QACvC,WAAW,EAAE,MAAM,CAAC;QACpB,eAAe,EAAE,aAAa,CAAC;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACtE,cAAc,EAAE,4BAA4B,CAAC;KAC9C,CAAC,CAAC;CACJ,CAAC,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAAC;IAChD,0EAA0E;IAC1E,IAAI,EAAE,aAAa,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACrC,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAAC;AAoHH;;;;;;;GAOG;AAEH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,EACnB,eAAe,CAAC,EAAE,SAAS,MAAM,EAAE,GAClC,mBAAmB,GAAG,IAAI,CAoC5B;AAsCD;;;;;;;GAOG;AAEH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,QAAQ,CAAC;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAM,GACvE,0BAA0B,CAiE5B;AAMD;;;;;;;GAOG;AAEH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,MAAM,GACX,IAAI,CAyDN"}