kibi-cli 2.21.2 → 2.22.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 (96) hide show
  1. package/dist/cli-register-foundation.d.ts.map +1 -1
  2. package/dist/cli-register-foundation.js +1 -0
  3. package/dist/commands/check.d.ts +0 -1
  4. package/dist/commands/check.d.ts.map +1 -1
  5. package/dist/commands/check.js +47 -111
  6. package/dist/commands/doctor.d.ts.map +1 -1
  7. package/dist/commands/doctor.js +96 -6
  8. package/dist/commands/init-helpers.d.ts +14 -1
  9. package/dist/commands/init-helpers.d.ts.map +1 -1
  10. package/dist/commands/init-helpers.js +49 -10
  11. package/dist/commands/init.d.ts +1 -0
  12. package/dist/commands/init.d.ts.map +1 -1
  13. package/dist/commands/init.js +12 -1
  14. package/dist/commands/legacy-storage-migration.d.ts +46 -1
  15. package/dist/commands/legacy-storage-migration.d.ts.map +1 -1
  16. package/dist/commands/legacy-storage-migration.js +219 -9
  17. package/dist/commands/migrate.d.ts.map +1 -1
  18. package/dist/commands/migrate.js +48 -182
  19. package/dist/commands/sync/manifest.d.ts.map +1 -1
  20. package/dist/commands/sync/manifest.js +9 -0
  21. package/dist/extractors/symbols-coordinator.js +1 -0
  22. package/dist/intent-search.d.ts.map +1 -1
  23. package/dist/intent-search.js +28 -6
  24. package/dist/operations/migration/inventory-rederive.d.ts +40 -1
  25. package/dist/operations/migration/inventory-rederive.d.ts.map +1 -1
  26. package/dist/operations/migration/inventory-rederive.js +99 -8
  27. package/dist/operations/migration/requirement-status.d.ts +25 -0
  28. package/dist/operations/migration/requirement-status.d.ts.map +1 -0
  29. package/dist/operations/migration/requirement-status.js +105 -0
  30. package/dist/operations/migration/schema6.d.ts +25 -0
  31. package/dist/operations/migration/schema6.d.ts.map +1 -1
  32. package/dist/operations/migration/schema6.js +265 -7
  33. package/dist/operations/migration/symbol-legacy-links.d.ts +51 -0
  34. package/dist/operations/migration/symbol-legacy-links.d.ts.map +1 -0
  35. package/dist/operations/migration/symbol-legacy-links.js +319 -0
  36. package/dist/operations/mutation/context-warning.d.ts +12 -2
  37. package/dist/operations/mutation/context-warning.d.ts.map +1 -1
  38. package/dist/operations/mutation/context-warning.js +6 -6
  39. package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
  40. package/dist/operations/mutation/source-authoring.js +130 -35
  41. package/dist/operations/mutation/types.d.ts +2 -1
  42. package/dist/operations/mutation/types.d.ts.map +1 -1
  43. package/dist/operations/mutation/upsert.d.ts +17 -2
  44. package/dist/operations/mutation/upsert.d.ts.map +1 -1
  45. package/dist/operations/mutation/upsert.js +28 -11
  46. package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
  47. package/dist/operations/mutation/validate-upsert.js +40 -8
  48. package/dist/operations/planning/apply-plan.d.ts.map +1 -1
  49. package/dist/operations/planning/apply-plan.js +18 -3
  50. package/dist/public/impact/diagnostics.d.ts.map +1 -1
  51. package/dist/public/impact/diagnostics.js +24 -14
  52. package/dist/public/operations/catalog.d.ts +3 -3
  53. package/dist/public/operations/check-executor.d.ts.map +1 -1
  54. package/dist/public/operations/check-executor.js +3 -0
  55. package/dist/public/operations/contracts.d.ts.map +1 -1
  56. package/dist/public/operations/contracts.js +6 -1
  57. package/dist/public/operations/discovery-executors.d.ts +2 -0
  58. package/dist/public/operations/discovery-executors.d.ts.map +1 -1
  59. package/dist/public/operations/discovery-executors.js +9 -2
  60. package/dist/public/operations/migration-plan.d.ts +2 -0
  61. package/dist/public/operations/migration-plan.d.ts.map +1 -1
  62. package/dist/public/operations/migration-plan.js +101 -16
  63. package/dist/public/operations/result-envelope.d.ts.map +1 -1
  64. package/dist/public/operations/result-envelope.js +27 -1
  65. package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
  66. package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
  67. package/dist/public/operations/specs/check-rules.generated.js +2 -1
  68. package/dist/public/operations/specs/check.d.ts +1 -1
  69. package/dist/public/operations/specs/planning.d.ts +2 -2
  70. package/dist/public/operations/specs/planning.js +2 -2
  71. package/dist/public/operations/symbol-granularity-check.d.ts +18 -0
  72. package/dist/public/operations/symbol-granularity-check.d.ts.map +1 -0
  73. package/dist/public/operations/symbol-granularity-check.js +175 -0
  74. package/dist/public/symbol-granularity.d.ts +17 -0
  75. package/dist/public/symbol-granularity.d.ts.map +1 -1
  76. package/dist/public/symbol-granularity.js +21 -0
  77. package/dist/traceability/evidence-model.d.ts +7 -3
  78. package/dist/traceability/evidence-model.d.ts.map +1 -1
  79. package/dist/traceability/staged-symbols-manifest.js +6 -5
  80. package/dist/traceability/validate.d.ts +14 -1
  81. package/dist/traceability/validate.d.ts.map +1 -1
  82. package/dist/traceability/validate.js +41 -0
  83. package/dist/utils/rule-registry.generated.d.ts +5 -0
  84. package/dist/utils/rule-registry.generated.d.ts.map +1 -1
  85. package/dist/utils/rule-registry.generated.js +6 -0
  86. package/package.json +3 -3
  87. package/src/public/impact/diagnostics.ts +29 -17
  88. package/src/public/operations/check-executor.ts +7 -0
  89. package/src/public/operations/contracts.ts +6 -1
  90. package/src/public/operations/discovery-executors.ts +12 -2
  91. package/src/public/operations/migration-plan.ts +100 -19
  92. package/src/public/operations/result-envelope.ts +34 -1
  93. package/src/public/operations/specs/check-rules.generated.ts +2 -1
  94. package/src/public/operations/specs/planning.ts +2 -2
  95. package/src/public/operations/symbol-granularity-check.ts +233 -0
  96. package/src/public/symbol-granularity.ts +37 -0
@@ -63,6 +63,8 @@ const GENERATED_COORD_FIELDS = [
63
63
  const GENERATED_MANIFEST_FIELDS = new Set([
64
64
  ...GENERATED_COORD_FIELDS,
65
65
  "coordinatesGeneratedAt",
66
+ // Transient refresh outcome from the coordinate enricher; never authored.
67
+ "coordinateRefreshFailure",
66
68
  ]);
67
69
  /**
68
70
  * Coarse symbol anchors for which AST per-declaration coordinates are not
@@ -159,7 +161,14 @@ function manifestEntryIdentity(entry) {
159
161
  * granularity_reason (so the whole-file fallback is gated off) or the
160
162
  * fallback itself produced no span.
161
163
  */
164
+ // implements REQ-generated-coordinate-persistence
162
165
  function coarseAnchorFailureReason(entry) {
166
+ // The enricher names the cause when the title is a declaration the symbol
167
+ // extractor never produces (a private class member): no refresh can bind
168
+ // it, so the remedy is to re-point or remove the symbol.
169
+ if (typeof entry.coordinateRefreshFailure === "string") {
170
+ return entry.coordinateRefreshFailure;
171
+ }
163
172
  const reason = entry.granularity_reason;
164
173
  if (!isCoarseGranularityReason(reason)) {
165
174
  return `extractor produced no coordinates; add symbol_role and granularity_reason ${COARSE_GRANULARITY_REASONS_PARENTHESIZED} to enable the whole-file coarse fallback`;
@@ -191,6 +191,7 @@ function withoutGeneratedCoordinates(entry) {
191
191
  "sourceEndLine",
192
192
  "sourceEndColumn",
193
193
  "coordinatesGeneratedAt",
194
+ "coordinateRefreshFailure",
194
195
  ]);
195
196
  return Object.fromEntries(Object.entries(entry).filter(([field]) => !generatedFields.has(field)));
196
197
  }
@@ -1 +1 @@
1
- {"version":3,"file":"intent-search.d.ts","sourceRoot":"","sources":["../src/intent-search.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,KAAK,kBAAkB,EAIxB,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAIvD,MAAM,MAAM,qBAAqB,GAC7B,QAAQ,GACR,SAAS,GACT,SAAS,GACT,aAAa,GACb,SAAS,CAAC;AAGd,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CACvC,OAAO,CAAC,MAAM,CAAC,qBAAqB,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAC1D,CAAC;AAGF,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC,CAAC;AAGH,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IACpD,cAAc,CAAC,EAAE,kBAAkB,CAAC;IACpC,eAAe,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC,CAAC;AAGH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC,CAAC;AAGH,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC,CAAC;AAGH,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,aAAa,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC5C,UAAU,EAAE,SAAS,eAAe,EAAE,CAAC;IACvC,kBAAkB,EAAE,OAAO,CAAC;CAC7B,CAAC,CAAC;AAGH,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG;IAC5C,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,CAAC;CACzC,CAAC;AAGF,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,WAAW,EAAE,WAAW,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;;;;OAKG;IACH,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC,CAAC;AAGH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;IACxC,OAAO,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACtC,QAAQ,EAAE,oBAAoB,CAAC;CAChC,CAAC,CAAC;AAEH,KAAK,SAAS,GAAG,QAAQ,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC,CAAC;AA2bH,2EAA2E;AAE3E,MAAM,MAAM,iBAAiB,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC;AA8B3D,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC5C,OAAO,EAAE,mBAAmB,EAC5B,aAAa,EAAE,MAAM,EACrB,UAAU,GAAE,SAAS,SAAS,EAAO,EACrC,SAAS,GAAE,iBAA6B,GACvC,OAAO,CAAC,kBAAkB,CAAC,CA8I7B;AAoCD,wBAAgB,SAAS,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,MAAM,CAO1E;AA8FD,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,mBAAmB,EAC5B,MAAM,EAAE,UAAU,EAClB,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,kBAAkB,CAAC,CAoD7B;AAGD,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI,CA0C1E"}
1
+ {"version":3,"file":"intent-search.d.ts","sourceRoot":"","sources":["../src/intent-search.ts"],"names":[],"mappings":"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"}
@@ -153,6 +153,22 @@ function tokens(value) {
153
153
  .split(" ")
154
154
  .filter((token) => token.length > 0 && !STOP_WORDS.has(token))));
155
155
  }
156
+ // Clause boundaries an agent writes when it packs several questions into one
157
+ // query: "user roles: how many can a user have, support role".
158
+ const CLAUSE_SEPARATOR = /[;:,!?\n]+|\.(?=\s|$)|\s[-\u2013\u2014]\s/;
159
+ const MIN_CLAUSE_TOKENS = 2;
160
+ /**
161
+ * The token sets of a compound query's clauses, or none for a single clause.
162
+ * A clause needs two signal tokens: one word alone matches too broadly to
163
+ * stand in for the question.
164
+ */
165
+ function queryClauses(query) {
166
+ const clauses = query
167
+ .split(CLAUSE_SEPARATOR)
168
+ .map((clause) => tokens(clause))
169
+ .filter((clause) => clause.length >= MIN_CLAUSE_TOKENS);
170
+ return clauses.length > 1 ? clauses : [];
171
+ }
156
172
  function stringValues(value) {
157
173
  if (typeof value === "string")
158
174
  return value.trim() ? [value] : [];
@@ -392,10 +408,11 @@ async function readBodies(entities, workspaceRoot, cache) {
392
408
  export async function rankIntentEntities(entities, options, workspaceRoot, graphEdges = [], bodyCache = new Map()) {
393
409
  const queryTokens = tokens(options.query);
394
410
  const facets = facetValues(options.semanticFacets);
395
- const allTokens = Array.from(new Set([
396
- ...queryTokens,
397
- ...facets.flatMap((facet) => tokens(facet.value)),
398
- ]));
411
+ const facetTokens = facets.flatMap((facet) => tokens(facet.value));
412
+ const allTokens = Array.from(new Set([...queryTokens, ...facetTokens]));
413
+ // Each clause of a compound question is also scored on its own, so the
414
+ // words of one clause do not dilute a match on another.
415
+ const clauseTokenSets = queryClauses(options.query).map((clause) => Array.from(new Set([...clause, ...facetTokens])));
399
416
  const bodies = await readBodies(entities, workspaceRoot, bodyCache);
400
417
  const documentFrequency = buildDocumentFrequency(entities, bodies);
401
418
  const supersededIds = new Set(graphEdges
@@ -428,8 +445,13 @@ export async function rankIntentEntities(entities, options, workspaceRoot, graph
428
445
  // already capped; unbounded parallel paths only add noise to receipts.
429
446
  const graphEvidence = (graphByEntity.get(entityId) ?? []).slice(0, 8);
430
447
  const body = bodies.get(entity) ?? null;
431
- const scored = scoreEntity(entity, allTokens, facets, sourceEvidence, graphEvidence, documentFrequency, entities.length, body, supersededIds.has(entityId), isProvenanceStub(entity));
432
- if (scored.score < minScore)
448
+ let scored;
449
+ for (const signalTokens of [allTokens, ...clauseTokenSets]) {
450
+ const candidate = scoreEntity(entity, signalTokens, facets, sourceEvidence, graphEvidence, documentFrequency, entities.length, body, supersededIds.has(entityId), isProvenanceStub(entity));
451
+ if (scored === undefined || candidate.score > scored.score)
452
+ scored = candidate;
453
+ }
454
+ if (scored === undefined || scored.score < minScore)
433
455
  continue;
434
456
  const snippet = body === null
435
457
  ? undefined
@@ -51,6 +51,26 @@ export type InventoryRederivation = Readonly<{
51
51
  contract: InventoryContract;
52
52
  /** SHA-256 of the canonical re-derived contract; the apply step re-checks it. */
53
53
  contractHash: string;
54
+ /**
55
+ * Grounding links (requires_*) whose target no longer grounds a modeled
56
+ * claim of the re-derived inventory. Empty for a safe re-derivation.
57
+ */
58
+ orphanedGrounding: readonly OrphanedGroundingLink[];
59
+ /**
60
+ * True when an unsafe re-derivation passes ingestion once exactly the
61
+ * orphaned grounding links are removed from the requirement's front
62
+ * matter. A person approves that explicitly; it is never automatic.
63
+ */
64
+ rederivableByDroppingGrounding: boolean;
65
+ }>;
66
+ /** A grounding link the re-derived inventory no longer supports. */
67
+ export type OrphanedGroundingLink = Readonly<{
68
+ type: string;
69
+ target: string;
70
+ /** The target fact's claim_key; null when it declares none. */
71
+ claimKey: string | null;
72
+ /** Declared in the requirement's front matter `links` (not a shard). */
73
+ inFrontMatter: boolean;
54
74
  }>;
55
75
  /**
56
76
  * Every current requirement whose stored inventory contract no longer matches
@@ -58,7 +78,14 @@ export type InventoryRederivation = Readonly<{
58
78
  * reports all of them instead of stopping at the first. `onlyId` limits the
59
79
  * scan to one requirement.
60
80
  */
61
- export declare function planInventoryRederivation(workspaceRoot: string, onlyId?: string): InventoryRederivation[];
81
+ export declare function planInventoryRederivation(workspaceRoot: string, onlyId?: string, options?: Readonly<{
82
+ /**
83
+ * Plan as if the requirement had this status: a requirement whose status
84
+ * is outside the current vocabulary is not validated, so its drift only
85
+ * shows once the status is mapped.
86
+ */
87
+ status?: string;
88
+ }>): InventoryRederivation[];
62
89
  export type InventoryRederivationOutcome = Readonly<{
63
90
  requirementId: string;
64
91
  path: string;
@@ -72,6 +99,18 @@ export type InventoryRederivationOutcome = Readonly<{
72
99
  * left unchanged, so repeated runs are no-ops.
73
100
  */
74
101
  export declare function applyInventoryRederivation(workspaceRoot: string, requirementId: string, expectedContractHash?: string): InventoryRederivationOutcome;
102
+ /**
103
+ * Apply an unsafe re-derivation a person approved: write the re-derived
104
+ * contract and remove exactly `expectedDrops`, the orphaned grounding links
105
+ * the plan listed, from the requirement's front matter. The current plan must
106
+ * still produce the approved contract hash and the same orphaned links, and
107
+ * the rewritten requirement must pass ingestion before anything is written;
108
+ * the grounding facts themselves are left alone.
109
+ */
110
+ export declare function applyInventoryRederivationDroppingGrounding(workspaceRoot: string, requirementId: string, expectedContractHash: string, expectedDrops: readonly Readonly<{
111
+ type: string;
112
+ target: string;
113
+ }>[]): InventoryRederivationOutcome;
75
114
  /** Apply every safe re-derivation; unsafe ones are returned untouched. */
76
115
  export declare function applySafeInventoryRederivations(workspaceRoot: string): {
77
116
  rederived: InventoryRederivationOutcome[];
@@ -1 +1 @@
1
- {"version":3,"file":"inventory-rederive.d.ts","sourceRoot":"","sources":["../../../src/operations/migration/inventory-rederive.ts"],"names":[],"mappings":"AA2EA,KAAK,cAAc,GAAG;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,gDAAgD;AAEhD,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EACF,MAAM,GACN,cAAc,GACd,cAAc,GACd,gBAAgB,GAChB,aAAa,GACb,gBAAgB,GAChB,aAAa,GACb,SAAS,CAAC;IACd,MAAM,CAAC,EAAE,QAAQ,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpD,KAAK,CAAC,EAAE,QAAQ,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpD,CAAC,CAAC;AAGH,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;CAC3B,CAAC,CAAC;AAEH,oEAAoE;AAEpE,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,0BAA0B,EAAE,MAAM,CAAC;IACnC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,kBAAkB,EAAE,SAAS,cAAc,EAAE,CAAC;IAC9C,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC,CAAC,CAAC;AAGH,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,+DAA+D;IAC/D,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,OAAO,EAAE,4BAA4B,CAAC;IACtC,OAAO,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACzC,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,iFAAiF;IACjF,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC,CAAC;AA2UH;;;;;GAKG;AAEH,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,MAAM,EACrB,MAAM,CAAC,EAAE,MAAM,GACd,qBAAqB,EAAE,CA+BzB;AA0FD,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,WAAW,GAAG,WAAW,CAAC;IACnC,OAAO,CAAC,EAAE,4BAA4B,CAAC;CACxC,CAAC,CAAC;AAEH;;;;;GAKG;AAEH,wBAAgB,0BAA0B,CACxC,aAAa,EAAE,MAAM,EACrB,aAAa,EAAE,MAAM,EACrB,oBAAoB,CAAC,EAAE,MAAM,GAC5B,4BAA4B,CA0C9B;AAED,0EAA0E;AAE1E,wBAAgB,+BAA+B,CAAC,aAAa,EAAE,MAAM,GAAG;IACtE,SAAS,EAAE,4BAA4B,EAAE,CAAC;IAC1C,MAAM,EAAE,qBAAqB,EAAE,CAAC;CACjC,CAaA"}
1
+ {"version":3,"file":"inventory-rederive.d.ts","sourceRoot":"","sources":["../../../src/operations/migration/inventory-rederive.ts"],"names":[],"mappings":"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"}
@@ -138,7 +138,7 @@ function relationshipsFor(id, extracted, shards) {
138
138
  for (const relationship of [...extracted, ...shards]) {
139
139
  if (relationship.from !== id)
140
140
  continue;
141
- unique.set(`${relationship.type}\u0000${relationship.from}\u0000${relationship.to}`, relationship);
141
+ unique.set(relationshipKey(relationship), relationship);
142
142
  }
143
143
  return [...unique.values()];
144
144
  }
@@ -267,20 +267,32 @@ function planOne(workspaceRoot, relativePath, entity, extracted, shards, facts)
267
267
  for (const claimKey of modeledBecameContext) {
268
268
  reasons.push(`modeled claim ${claimKey} is now classified as context (${inventory.find((entry) => entry.claim_key === claimKey)?.role ?? "context"}); its grounding cannot stay`);
269
269
  }
270
+ const modeledKeys = inventory
271
+ .filter((entry) => entry.status === "modeled")
272
+ .map((entry) => entry.claim_key);
273
+ const declared = new Set(extracted
274
+ .filter((relationship) => relationship.from === entity.id)
275
+ .map(relationshipKey));
270
276
  const groundingKeys = [];
277
+ const orphanedGrounding = [];
271
278
  for (const relationship of relationships) {
272
279
  if (!GROUNDING_RELATIONSHIPS.has(relationship.type))
273
280
  continue;
274
281
  const claimKey = facts.claimKey(relationship.to);
282
+ if (claimKey === undefined || !modeledKeys.includes(claimKey)) {
283
+ orphanedGrounding.push({
284
+ type: relationship.type,
285
+ target: relationship.to,
286
+ claimKey: claimKey ?? null,
287
+ inFrontMatter: declared.has(relationshipKey(relationship)),
288
+ });
289
+ }
275
290
  if (claimKey === undefined) {
276
291
  reasons.push(`grounding target ${relationship.to} (${relationship.type}) declares no claim_key`);
277
292
  continue;
278
293
  }
279
294
  groundingKeys.push(claimKey);
280
295
  }
281
- const modeledKeys = inventory
282
- .filter((entry) => entry.status === "modeled")
283
- .map((entry) => entry.claim_key);
284
296
  for (const claimKey of new Set(groundingKeys)) {
285
297
  if (modeledKeys.includes(claimKey))
286
298
  continue;
@@ -298,6 +310,14 @@ function planOne(workspaceRoot, relativePath, entity, extracted, shards, facts)
298
310
  for (const error of after.errors) {
299
311
  reasons.push(`re-derived inventory would still fail ingestion: ${error}`);
300
312
  }
313
+ const orphaned = new Set(orphanedGrounding.map((link) => relationshipKey({ type: link.type, from: entity.id, to: link.target })));
314
+ const rederivableByDroppingGrounding = reasons.length > 0 &&
315
+ orphanedGrounding.length > 0 &&
316
+ // A target without claim_key may ground something else (a property
317
+ // value, for example); only links to a claim that is no longer modeled
318
+ // are dropped, and only from the requirement's own front matter.
319
+ orphanedGrounding.every((link) => link.inFrontMatter && link.claimKey !== null) &&
320
+ validateSemanticInventoryBoundary(nextPayload, relationships.filter((relationship) => !orphaned.has(relationshipKey(relationship))), analyzeSemanticAdvisorInput({ payload: nextPayload }).receipt).errors.length === 0;
301
321
  return {
302
322
  requirementId: entity.id,
303
323
  path: relativePath,
@@ -310,8 +330,13 @@ function planOne(workspaceRoot, relativePath, entity, extracted, shards, facts)
310
330
  contractHash: createHash("sha256")
311
331
  .update(canonicalJson(contract))
312
332
  .digest("hex"),
333
+ orphanedGrounding,
334
+ rederivableByDroppingGrounding,
313
335
  };
314
336
  }
337
+ function relationshipKey(relationship) {
338
+ return `${relationship.type}\u0000${relationship.from}\u0000${relationship.to}`;
339
+ }
315
340
  function readShardRelationships(workspaceRoot) {
316
341
  try {
317
342
  return readAllShards(path.join(workspaceRoot, ".kb")).map(({ type, from, to }) => ({ type, from, to }));
@@ -328,7 +353,7 @@ function readShardRelationships(workspaceRoot) {
328
353
  * scan to one requirement.
329
354
  */
330
355
  // implements REQ-kibi-proposition-complete-ingestion, REQ-cli-schema-migration
331
- export function planInventoryRederivation(workspaceRoot, onlyId) {
356
+ export function planInventoryRederivation(workspaceRoot, onlyId, options = {}) {
332
357
  const shards = readShardRelationships(workspaceRoot);
333
358
  const facts = new FactClaimIndex(workspaceRoot);
334
359
  const plans = [];
@@ -347,7 +372,9 @@ export function planInventoryRederivation(workspaceRoot, onlyId) {
347
372
  }
348
373
  if (onlyId !== undefined && result.entity.id !== onlyId)
349
374
  continue;
350
- const plan = planOne(workspaceRoot, file.relativePath, result.entity, result.relationships, shards, facts);
375
+ const plan = planOne(workspaceRoot, file.relativePath, options.status === undefined
376
+ ? result.entity
377
+ : { ...result.entity, status: options.status }, result.relationships, shards, facts);
351
378
  if (plan !== null)
352
379
  plans.push(plan);
353
380
  }
@@ -357,7 +384,7 @@ export function planInventoryRederivation(workspaceRoot, onlyId) {
357
384
  * Rewrite the inventory contract keys of one requirement's frontmatter and
358
385
  * confirm every other frontmatter field reads back unchanged.
359
386
  */
360
- function rewriteContract(content, contract) {
387
+ function rewriteContract(content, contract, dropLinks = []) {
361
388
  const slice = sliceFrontmatter(content);
362
389
  if (slice === null)
363
390
  return null;
@@ -365,6 +392,24 @@ function rewriteContract(content, contract) {
365
392
  if (document.errors.length > 0)
366
393
  return null;
367
394
  const current = document.toJS();
395
+ const dropped = (link) => isRecord(link) &&
396
+ dropLinks.some((drop) => drop.type === link.type && drop.target === link.target);
397
+ const keptLinks = Array.isArray(current.links)
398
+ ? current.links.filter((link) => !dropped(link))
399
+ : current.links;
400
+ if (dropLinks.length > 0) {
401
+ if (!Array.isArray(current.links))
402
+ return null;
403
+ if (current.links.length - keptLinks.length !==
404
+ dropLinks.length)
405
+ return null;
406
+ for (let index = current.links.length - 1; index >= 0; index--) {
407
+ if (dropped(current.links[index]))
408
+ document.deleteIn(["links", index]);
409
+ }
410
+ if (keptLinks.length === 0)
411
+ document.delete("links");
412
+ }
368
413
  const flowSpan = (span) => {
369
414
  const node = document.createNode(span);
370
415
  node.flow = true;
@@ -425,7 +470,11 @@ function rewriteContract(content, contract) {
425
470
  ])) {
426
471
  const expected = key in contract
427
472
  ? contract[key]
428
- : before[key];
473
+ : key === "links" && dropLinks.length > 0
474
+ ? keptLinks.length > 0
475
+ ? keptLinks
476
+ : undefined
477
+ : before[key];
429
478
  if (!isDeepStrictEqual(after[key], expected))
430
479
  return null;
431
480
  }
@@ -472,6 +521,48 @@ export function applyInventoryRederivation(workspaceRoot, requirementId, expecte
472
521
  summary: plan.summary,
473
522
  };
474
523
  }
524
+ function linkKeys(links) {
525
+ return JSON.stringify(links.map((link) => `${link.type}\u0000${link.target}`).sort());
526
+ }
527
+ /**
528
+ * Apply an unsafe re-derivation a person approved: write the re-derived
529
+ * contract and remove exactly `expectedDrops`, the orphaned grounding links
530
+ * the plan listed, from the requirement's front matter. The current plan must
531
+ * still produce the approved contract hash and the same orphaned links, and
532
+ * the rewritten requirement must pass ingestion before anything is written;
533
+ * the grounding facts themselves are left alone.
534
+ */
535
+ // implements REQ-kibi-proposition-complete-ingestion, REQ-cli-schema-migration
536
+ export function applyInventoryRederivationDroppingGrounding(workspaceRoot, requirementId, expectedContractHash, expectedDrops) {
537
+ const plan = planInventoryRederivation(workspaceRoot, requirementId).find((candidate) => candidate.requirementId === requirementId);
538
+ if (plan === undefined ||
539
+ !plan.rederivableByDroppingGrounding ||
540
+ plan.contractHash !== expectedContractHash ||
541
+ linkKeys(plan.orphanedGrounding) !== linkKeys(expectedDrops)) {
542
+ throw new Error(`Requirement ${requirementId} changed since planning; rerun kibi migrate and approve the new plan.`);
543
+ }
544
+ const absolute = path.join(workspaceRoot, plan.path);
545
+ const content = readText(absolute);
546
+ const next = content === null
547
+ ? null
548
+ : rewriteContract(content, plan.contract, plan.orphanedGrounding);
549
+ if (next === null) {
550
+ throw new Error(`Requirement ${requirementId}: the re-derived inventory and the dropped grounding links could not be written without changing other frontmatter fields.`);
551
+ }
552
+ // Fail closed: the rewritten requirement must pass ingestion as sync sees it.
553
+ const reread = extractFromMarkdownString(next, absolute);
554
+ const remaining = planOne(workspaceRoot, plan.path, reread.entity, reread.relationships, readShardRelationships(workspaceRoot), new FactClaimIndex(workspaceRoot));
555
+ if (remaining !== null) {
556
+ throw new Error(`Requirement ${requirementId}: the rewrite would still fail ingestion (${remaining.errors.join("; ")}); nothing was written.`);
557
+ }
558
+ writeFileAtomically(absolute, next);
559
+ return {
560
+ requirementId,
561
+ path: plan.path,
562
+ outcome: "rederived",
563
+ summary: plan.summary,
564
+ };
565
+ }
475
566
  /** Apply every safe re-derivation; unsafe ones are returned untouched. */
476
567
  // implements REQ-kibi-proposition-complete-ingestion, REQ-cli-schema-migration
477
568
  export function applySafeInventoryRederivations(workspaceRoot) {
@@ -0,0 +1,25 @@
1
+ import { type InventoryRederivation } from "./inventory-rederive.js";
2
+ /**
3
+ * Suggested current status for ADR or lifecycle vocabulary found on
4
+ * requirements: decided or still-proposed intent stays `open`; retired
5
+ * intent is `closed`.
6
+ */
7
+ export declare const SUGGESTED_REQUIREMENT_STATUS: Readonly<Record<string, string>>;
8
+ /** One requirement whose status is outside the vocabulary. */
9
+ export type RequirementStatusFinding = Readonly<{
10
+ requirementId: string;
11
+ path: string;
12
+ status: string;
13
+ /** The suggested current status; null when Kibi has no suggestion. */
14
+ suggestedStatus: string | null;
15
+ /** Inventory drift the requirement shows once it has the suggested status. */
16
+ latentDrift: InventoryRederivation | null;
17
+ }>;
18
+ /** Every requirement whose authored status is outside the vocabulary. */
19
+ export declare function planRequirementStatusMappings(workspaceRoot: string): RequirementStatusFinding[];
20
+ /**
21
+ * Set the status of one requirement from `from` to `to`, replacing only its
22
+ * `status` line. Refuses when the authored status is no longer `from`.
23
+ */
24
+ export declare function applyRequirementStatusMapping(workspaceRoot: string, relativePath: string, from: string, to: string): void;
25
+ //# sourceMappingURL=requirement-status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requirement-status.d.ts","sourceRoot":"","sources":["../../../src/operations/migration/requirement-status.ts"],"names":[],"mappings":"AAmBA,OAAO,EACL,KAAK,qBAAqB,EAE3B,MAAM,yBAAyB,CAAC;AA8BjC;;;;GAIG;AAEH,eAAO,MAAM,4BAA4B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOzE,CAAC;AAEF,8DAA8D;AAE9D,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,8EAA8E;IAC9E,WAAW,EAAE,qBAAqB,GAAG,IAAI,CAAC;CAC3C,CAAC,CAAC;AAYH,yEAAyE;AAEzE,wBAAgB,6BAA6B,CAC3C,aAAa,EAAE,MAAM,GACpB,wBAAwB,EAAE,CA8B5B;AAED;;;GAGG;AAEH,wBAAgB,6BAA6B,CAC3C,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,GACT,IAAI,CAaN"}
@@ -0,0 +1,105 @@
1
+ /*
2
+ Kibi — repo-local, per-branch, queryable long-term memory for software projects
3
+ Copyright (C) 2026 Piotr Franczyk
4
+
5
+ This program is free software: you can redistribute it and/or modify
6
+ it under the terms of the GNU Affero General Public License as published by
7
+ the Free Software Foundation, either version 3 of the License, or
8
+ (at your option) any later version.
9
+
10
+ This program is distributed in the hope that it will be useful,
11
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ GNU Affero General Public License for more details.
14
+
15
+ You should have received a copy of the GNU Affero General Public License
16
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+ */
18
+ import path from "node:path";
19
+ import { planInventoryRederivation, } from "./inventory-rederive.js";
20
+ import { listLaneMarkdownFiles, readText, readTopLevelField, sliceFrontmatter, withTopLevelField, writeFileAtomically, } from "./kb-sources.js";
21
+ /**
22
+ * Requirement statuses outside the current vocabulary (`req-status-vocabulary`).
23
+ *
24
+ * A requirement with ADR vocabulary such as `status: accepted` compiles, but
25
+ * it is not a current requirement: the proof ladder skips it and the
26
+ * ingestion boundary does not validate its semantic inventory, so inventory
27
+ * drift stays hidden until someone maps the status. Which current status a
28
+ * legacy one means is a semantic choice, so the mapping is only suggested;
29
+ * the latent drift is computed as if the suggestion were applied.
30
+ */
31
+ /** Statuses `kibi check` accepts on a requirement (canonical and legacy). */
32
+ const REQUIREMENT_STATUSES = new Set([
33
+ "open",
34
+ "in_progress",
35
+ "closed",
36
+ "active",
37
+ "approved",
38
+ ]);
39
+ /**
40
+ * Suggested current status for ADR or lifecycle vocabulary found on
41
+ * requirements: decided or still-proposed intent stays `open`; retired
42
+ * intent is `closed`.
43
+ */
44
+ // implements REQ-cli-schema-migration
45
+ export const SUGGESTED_REQUIREMENT_STATUS = {
46
+ accepted: "open",
47
+ proposed: "open",
48
+ draft: "open",
49
+ deprecated: "closed",
50
+ superseded: "closed",
51
+ rejected: "closed",
52
+ };
53
+ function statusOf(content) {
54
+ const slice = sliceFrontmatter(content);
55
+ return slice === null ? undefined : readTopLevelField(slice.text, "status");
56
+ }
57
+ function idOf(content) {
58
+ const slice = sliceFrontmatter(content);
59
+ return slice === null ? undefined : readTopLevelField(slice.text, "id");
60
+ }
61
+ /** Every requirement whose authored status is outside the vocabulary. */
62
+ // implements REQ-cli-schema-migration
63
+ export function planRequirementStatusMappings(workspaceRoot) {
64
+ const findings = [];
65
+ for (const file of listLaneMarkdownFiles(workspaceRoot, ["requirements"])) {
66
+ const content = readText(file.absolutePath);
67
+ if (content === null)
68
+ continue;
69
+ const status = statusOf(content);
70
+ if (typeof status !== "string" || REQUIREMENT_STATUSES.has(status))
71
+ continue;
72
+ const id = idOf(content);
73
+ const requirementId = typeof id === "string" && id.length > 0
74
+ ? id
75
+ : path.basename(file.relativePath, ".md");
76
+ const suggestedStatus = SUGGESTED_REQUIREMENT_STATUS[status] ?? null;
77
+ findings.push({
78
+ requirementId,
79
+ path: file.relativePath,
80
+ status,
81
+ suggestedStatus,
82
+ latentDrift: suggestedStatus === null
83
+ ? null
84
+ : (planInventoryRederivation(workspaceRoot, requirementId, {
85
+ status: suggestedStatus,
86
+ }).find((plan) => plan.requirementId === requirementId) ?? null),
87
+ });
88
+ }
89
+ return findings.sort((left, right) => left.requirementId.localeCompare(right.requirementId));
90
+ }
91
+ /**
92
+ * Set the status of one requirement from `from` to `to`, replacing only its
93
+ * `status` line. Refuses when the authored status is no longer `from`.
94
+ */
95
+ // implements REQ-cli-schema-migration
96
+ export function applyRequirementStatusMapping(workspaceRoot, relativePath, from, to) {
97
+ const absolute = path.join(workspaceRoot, relativePath);
98
+ const content = readText(absolute);
99
+ if (content === null || statusOf(content) !== from)
100
+ throw new Error(`${relativePath} no longer has status ${from}; rerun kibi migrate and approve the new plan.`);
101
+ const next = withTopLevelField(content, "status", to);
102
+ if (next === null)
103
+ throw new Error(`${relativePath}: status could not be set to ${to} without changing other frontmatter fields; set it by hand.`);
104
+ writeFileAtomically(absolute, next);
105
+ }
@@ -10,10 +10,25 @@ export declare const DECISION_FIRMNESS_SCHEMA_VERSION = 9;
10
10
  export declare const SEMANTIC_INVENTORY_REDERIVE_CODE = "semantic_inventory_rederive";
11
11
  /** Review: a drifted inventory Kibi cannot re-derive safely. */
12
12
  export declare const SEMANTIC_INVENTORY_REVIEW_CODE = "semantic_inventory_review";
13
+ /**
14
+ * Review, applied only when approved by id: re-derive a drifted inventory and
15
+ * drop the grounding links that no longer ground a modeled claim.
16
+ */
17
+ export declare const SEMANTIC_INVENTORY_REDERIVE_DROP_GROUNDING_CODE = "semantic_inventory_rederive_drop_grounding";
18
+ /** Review, applied only when approved by id: map a legacy requirement status. */
19
+ export declare const REQ_STATUS_VOCABULARY_MAP_CODE = "req_status_vocabulary_map";
13
20
  /** Automatic: stamp `origin: {kind: migration}` on authored entities. */
14
21
  export declare const ENTITY_ORIGIN_BACKFILL_CODE = "entity_origin_backfill";
15
22
  export declare const ENTITY_ORIGIN_BACKFILL_ACTION_ID = "entity-origin-backfill";
16
23
  export { CLOSE_SUPERSEDED_REQUIREMENTS_CODE, MIGRATION_SYNC_ACTION_ID, MIGRATION_SYNC_CODE, SOURCE_PATH_REWRITE_CODE, };
24
+ /**
25
+ * One action per requirement whose status is outside the vocabulary: a
26
+ * review (the target status is a semantic choice) carrying the suggested
27
+ * mapping and the inventory drift the requirement shows once mapped. With a
28
+ * suggestion it is executable when approved by id; the re-derivation of the
29
+ * latent drift depends on it.
30
+ */
31
+ export declare function requirementStatusActions(workspaceRoot: string): MigrationAction[];
17
32
  /**
18
33
  * Exceptions without approved_by, read from authored sources so the list is
19
34
  * available before the KB compiles.
@@ -51,6 +66,11 @@ export declare function buildLifecycleRepairActions(workspaceRoot: string): {
51
66
  actions: MigrationAction[];
52
67
  sourceRewriteActionIds: string[];
53
68
  };
69
+ /**
70
+ * The automatic legacy-link pass over `.kb/symbols.yaml`, bound to the
71
+ * manifest bytes it was planned from; null when no link needs a mark.
72
+ */
73
+ export declare function symbolLegacyLinkAction(workspaceRoot: string): MigrationAction | null;
54
74
  /** The sync that recompiles sources rewritten by earlier actions. */
55
75
  export declare function migrationSyncAction(dependsOn: readonly string[]): MigrationAction;
56
76
  type ApplyContext = Readonly<{
@@ -59,5 +79,10 @@ type ApplyContext = Readonly<{
59
79
  }>;
60
80
  /** Execute one automatic action produced by this module. */
61
81
  export declare function applySchema6MigrationAction(action: MigrationAction, context: ApplyContext): Promise<void>;
82
+ /**
83
+ * Review actions Kibi can execute, but only when a person approves them by
84
+ * id (`--approved-action`): `--apply-safe` selects automatic actions alone.
85
+ */
86
+ export declare const SCHEMA6_APPROVABLE_REVIEW_CODES: ReadonlySet<string>;
62
87
  export declare const SCHEMA6_AUTOMATIC_CODES: ReadonlySet<string>;
63
88
  //# sourceMappingURL=schema6.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema6.d.ts","sourceRoot":"","sources":["../../../src/operations/migration/schema6.ts"],"names":[],"mappings":"AAuBA,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAEL,kCAAkC,EAClC,wBAAwB,EACxB,mBAAmB,EAEnB,wBAAwB,EAOzB,MAAM,kDAAkD,CAAC;AAyC1D,gEAAgE;AAEhE,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC,+EAA+E;AAE/E,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAE7C,4DAA4D;AAE5D,eAAO,MAAM,gCAAgC,IAAI,CAAC;AAElD,yEAAyE;AAEzE,eAAO,MAAM,gCAAgC,gCAAgC,CAAC;AAC9E,gEAAgE;AAEhE,eAAO,MAAM,8BAA8B,8BAA8B,CAAC;AAC1E,yEAAyE;AAEzE,eAAO,MAAM,2BAA2B,2BAA2B,CAAC;AAEpE,eAAO,MAAM,gCAAgC,2BAA2B,CAAC;AACzE,OAAO,EACL,kCAAkC,EAClC,wBAAwB,EACxB,mBAAmB,EACnB,wBAAwB,GACzB,CAAC;AAwEF;;;GAGG;AAEH,wBAAgB,+BAA+B,CAC7C,aAAa,EAAE,MAAM,GACpB,KAAK,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAsDnE;AAGD,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;IACpC,uDAAuD;IACvD,sBAAsB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC,CAAC,CAAC;AAEH;;;;;;GAMG;AAEH,wBAAgB,6BAA6B,CAAC,KAAK,EAAE;IACnD,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC,GAAG,wBAAwB,CAoM3B;AAED;;;;;;GAMG;AAEH,wBAAgB,2BAA2B,CAAC,aAAa,EAAE,MAAM,GAAG;IAClE,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,sBAAsB,EAAE,MAAM,EAAE,CAAC;CAClC,CAoCA;AAED,qEAAqE;AAErE,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,eAAe,CAEjB;AA0CD,KAAK,YAAY,GAAG,QAAQ,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC,CAAC;AAEH,4DAA4D;AAE5D,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC,CA0Ef;AAGD,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,MAAM,CAUtD,CAAC"}
1
+ {"version":3,"file":"schema6.d.ts","sourceRoot":"","sources":["../../../src/operations/migration/schema6.ts"],"names":[],"mappings":"AAuBA,OAAO,EACL,KAAK,eAAe,EAErB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAEL,kCAAkC,EAClC,wBAAwB,EACxB,mBAAmB,EAEnB,wBAAwB,EAOzB,MAAM,kDAAkD,CAAC;AAoD1D,gEAAgE;AAEhE,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC,+EAA+E;AAE/E,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAE7C,4DAA4D;AAE5D,eAAO,MAAM,gCAAgC,IAAI,CAAC;AAElD,yEAAyE;AAEzE,eAAO,MAAM,gCAAgC,gCAAgC,CAAC;AAC9E,gEAAgE;AAEhE,eAAO,MAAM,8BAA8B,8BAA8B,CAAC;AAC1E;;;GAGG;AAEH,eAAO,MAAM,+CAA+C,+CACd,CAAC;AAC/C,iFAAiF;AAEjF,eAAO,MAAM,8BAA8B,8BAA8B,CAAC;AAC1E,yEAAyE;AAEzE,eAAO,MAAM,2BAA2B,2BAA2B,CAAC;AAEpE,eAAO,MAAM,gCAAgC,2BAA2B,CAAC;AACzE,OAAO,EACL,kCAAkC,EAClC,wBAAwB,EACxB,mBAAmB,EACnB,wBAAwB,GACzB,CAAC;AAgLF;;;;;;GAMG;AAEH,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,MAAM,GACpB,eAAe,EAAE,CAqEnB;AAyBD;;;GAGG;AAEH,wBAAgB,+BAA+B,CAC7C,aAAa,EAAE,MAAM,GACpB,KAAK,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAsDnE;AAGD,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,OAAO,EAAE,SAAS,eAAe,EAAE,CAAC;IACpC,uDAAuD;IACvD,sBAAsB,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CAChC,CAAC,CAAC;AAEH;;;;;;GAMG;AAEH,wBAAgB,6BAA6B,CAAC,KAAK,EAAE;IACnD,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC,GAAG,wBAAwB,CAgN3B;AAED;;;;;;GAMG;AAEH,wBAAgB,2BAA2B,CAAC,aAAa,EAAE,MAAM,GAAG;IAClE,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,sBAAsB,EAAE,MAAM,EAAE,CAAC;CAClC,CAoCA;AAED;;;GAGG;AAEH,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,MAAM,GACpB,eAAe,GAAG,IAAI,CAqBxB;AAED,qEAAqE;AAErE,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,eAAe,CAEjB;AA0CD,KAAK,YAAY,GAAG,QAAQ,CAAC;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC,CAAC;AAEH,4DAA4D;AAE5D,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,eAAe,EACvB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC,CAgHf;AAED;;;GAGG;AAEH,eAAO,MAAM,+BAA+B,EAAE,WAAW,CAAC,MAAM,CAK9D,CAAC;AAGH,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,MAAM,CAWtD,CAAC"}