kibi-cli 2.21.0 → 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 (164) hide show
  1. package/dist/cli-operation-metadata.d.ts +1 -1
  2. package/dist/cli-operation-metadata.js +1 -1
  3. package/dist/cli-register-foundation.d.ts.map +1 -1
  4. package/dist/cli-register-foundation.js +1 -0
  5. package/dist/commands/check.d.ts +0 -1
  6. package/dist/commands/check.d.ts.map +1 -1
  7. package/dist/commands/check.js +47 -111
  8. package/dist/commands/doctor.d.ts.map +1 -1
  9. package/dist/commands/doctor.js +107 -5
  10. package/dist/commands/init-helpers.d.ts +14 -1
  11. package/dist/commands/init-helpers.d.ts.map +1 -1
  12. package/dist/commands/init-helpers.js +49 -10
  13. package/dist/commands/init.d.ts +1 -0
  14. package/dist/commands/init.d.ts.map +1 -1
  15. package/dist/commands/init.js +27 -4
  16. package/dist/commands/legacy-storage-migration.d.ts +46 -1
  17. package/dist/commands/legacy-storage-migration.d.ts.map +1 -1
  18. package/dist/commands/legacy-storage-migration.js +244 -9
  19. package/dist/commands/migrate.d.ts.map +1 -1
  20. package/dist/commands/migrate.js +150 -166
  21. package/dist/commands/sync/manifest.d.ts.map +1 -1
  22. package/dist/commands/sync/manifest.js +9 -0
  23. package/dist/commands/sync/persistence.d.ts.map +1 -1
  24. package/dist/commands/sync/persistence.js +4 -0
  25. package/dist/decision-firmness.d.ts +39 -0
  26. package/dist/decision-firmness.d.ts.map +1 -0
  27. package/dist/decision-firmness.js +115 -0
  28. package/dist/extractors/markdown.d.ts +2 -0
  29. package/dist/extractors/markdown.d.ts.map +1 -1
  30. package/dist/extractors/markdown.js +14 -0
  31. package/dist/extractors/symbols-coordinator.js +1 -0
  32. package/dist/intent-search.d.ts.map +1 -1
  33. package/dist/intent-search.js +28 -6
  34. package/dist/operations/migration/inventory-rederive.d.ts +40 -1
  35. package/dist/operations/migration/inventory-rederive.d.ts.map +1 -1
  36. package/dist/operations/migration/inventory-rederive.js +99 -8
  37. package/dist/operations/migration/requirement-status.d.ts +25 -0
  38. package/dist/operations/migration/requirement-status.d.ts.map +1 -0
  39. package/dist/operations/migration/requirement-status.js +105 -0
  40. package/dist/operations/migration/schema6.d.ts +27 -0
  41. package/dist/operations/migration/schema6.d.ts.map +1 -1
  42. package/dist/operations/migration/schema6.js +308 -7
  43. package/dist/operations/migration/supersedes-reason.d.ts +26 -0
  44. package/dist/operations/migration/supersedes-reason.d.ts.map +1 -0
  45. package/dist/operations/migration/supersedes-reason.js +69 -0
  46. package/dist/operations/migration/symbol-legacy-links.d.ts +51 -0
  47. package/dist/operations/migration/symbol-legacy-links.d.ts.map +1 -0
  48. package/dist/operations/migration/symbol-legacy-links.js +319 -0
  49. package/dist/operations/modeling/predicate-applyplan.d.ts.map +1 -1
  50. package/dist/operations/modeling/predicate-applyplan.js +10 -2
  51. package/dist/operations/modeling/predicate-loader.d.ts.map +1 -1
  52. package/dist/operations/modeling/predicate-loader.js +11 -0
  53. package/dist/operations/modeling/predicate-types.d.ts +32 -1
  54. package/dist/operations/modeling/predicate-types.d.ts.map +1 -1
  55. package/dist/operations/modeling/suggest-predicates.d.ts.map +1 -1
  56. package/dist/operations/modeling/suggest-predicates.js +175 -35
  57. package/dist/operations/mutation/context-warning.d.ts +12 -2
  58. package/dist/operations/mutation/context-warning.d.ts.map +1 -1
  59. package/dist/operations/mutation/context-warning.js +6 -6
  60. package/dist/operations/mutation/delete.d.ts +5 -1
  61. package/dist/operations/mutation/delete.d.ts.map +1 -1
  62. package/dist/operations/mutation/delete.js +223 -17
  63. package/dist/operations/mutation/serialization.d.ts.map +1 -1
  64. package/dist/operations/mutation/serialization.js +1 -0
  65. package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
  66. package/dist/operations/mutation/source-authoring.js +130 -35
  67. package/dist/operations/mutation/types.d.ts +39 -1
  68. package/dist/operations/mutation/types.d.ts.map +1 -1
  69. package/dist/operations/mutation/upsert.d.ts +17 -2
  70. package/dist/operations/mutation/upsert.d.ts.map +1 -1
  71. package/dist/operations/mutation/upsert.js +82 -13
  72. package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
  73. package/dist/operations/mutation/validate-upsert.js +40 -8
  74. package/dist/operations/planning/apply-plan.d.ts +6 -1
  75. package/dist/operations/planning/apply-plan.d.ts.map +1 -1
  76. package/dist/operations/planning/apply-plan.js +26 -5
  77. package/dist/public/impact/diagnostics.d.ts.map +1 -1
  78. package/dist/public/impact/diagnostics.js +24 -14
  79. package/dist/public/operations/catalog.d.ts +14 -5
  80. package/dist/public/operations/catalog.d.ts.map +1 -1
  81. package/dist/public/operations/check-executor.d.ts.map +1 -1
  82. package/dist/public/operations/check-executor.js +6 -0
  83. package/dist/public/operations/contracts.d.ts.map +1 -1
  84. package/dist/public/operations/contracts.js +35 -2
  85. package/dist/public/operations/decision-firmness.d.ts +34 -0
  86. package/dist/public/operations/decision-firmness.d.ts.map +1 -0
  87. package/dist/public/operations/decision-firmness.js +216 -0
  88. package/dist/public/operations/discovery-executors.d.ts +2 -0
  89. package/dist/public/operations/discovery-executors.d.ts.map +1 -1
  90. package/dist/public/operations/discovery-executors.js +25 -4
  91. package/dist/public/operations/migration-plan.d.ts +2 -0
  92. package/dist/public/operations/migration-plan.d.ts.map +1 -1
  93. package/dist/public/operations/migration-plan.js +101 -16
  94. package/dist/public/operations/result-envelope.d.ts.map +1 -1
  95. package/dist/public/operations/result-envelope.js +27 -1
  96. package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
  97. package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
  98. package/dist/public/operations/specs/check-rules.generated.js +6 -1
  99. package/dist/public/operations/specs/check.d.ts +1 -1
  100. package/dist/public/operations/specs/mutation-schemas.d.ts +5 -0
  101. package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
  102. package/dist/public/operations/specs/mutation-schemas.js +5 -0
  103. package/dist/public/operations/specs/mutation.d.ts +6 -2
  104. package/dist/public/operations/specs/mutation.d.ts.map +1 -1
  105. package/dist/public/operations/specs/mutation.js +6 -2
  106. package/dist/public/operations/specs/planning.d.ts +2 -2
  107. package/dist/public/operations/specs/planning.js +2 -2
  108. package/dist/public/operations/specs/upsert.d.ts +5 -0
  109. package/dist/public/operations/specs/upsert.d.ts.map +1 -1
  110. package/dist/public/operations/symbol-granularity-check.d.ts +18 -0
  111. package/dist/public/operations/symbol-granularity-check.d.ts.map +1 -0
  112. package/dist/public/operations/symbol-granularity-check.js +175 -0
  113. package/dist/public/schemas/entity.d.ts.map +1 -1
  114. package/dist/public/schemas/entity.js +11 -0
  115. package/dist/public/skills/kibi-traceability/SKILL.md +6 -4
  116. package/dist/public/skills/kibi-usage/SKILL.md +50 -10
  117. package/dist/public/skills/kibi-usage/resources/source-authoring.md +4 -2
  118. package/dist/public/symbol-granularity.d.ts +17 -0
  119. package/dist/public/symbol-granularity.d.ts.map +1 -1
  120. package/dist/public/symbol-granularity.js +21 -0
  121. package/dist/relationships/shards.d.ts +10 -0
  122. package/dist/relationships/shards.d.ts.map +1 -1
  123. package/dist/relationships/shards.js +27 -11
  124. package/dist/schemas/entity.schema.json +28 -0
  125. package/dist/search-answer.d.ts +31 -2
  126. package/dist/search-answer.d.ts.map +1 -1
  127. package/dist/search-answer.js +115 -17
  128. package/dist/traceability/evidence-model.d.ts +7 -3
  129. package/dist/traceability/evidence-model.d.ts.map +1 -1
  130. package/dist/traceability/staged-symbols-manifest.js +6 -5
  131. package/dist/traceability/validate.d.ts +14 -1
  132. package/dist/traceability/validate.d.ts.map +1 -1
  133. package/dist/traceability/validate.js +41 -0
  134. package/dist/types/entities.d.ts +4 -0
  135. package/dist/types/entities.d.ts.map +1 -1
  136. package/dist/utils/kb-manifest.d.ts +6 -0
  137. package/dist/utils/kb-manifest.d.ts.map +1 -1
  138. package/dist/utils/kb-manifest.js +6 -0
  139. package/dist/utils/rule-registry.generated.d.ts +26 -0
  140. package/dist/utils/rule-registry.generated.d.ts.map +1 -1
  141. package/dist/utils/rule-registry.generated.js +31 -0
  142. package/dist/utils/schema-version.d.ts +1 -1
  143. package/dist/utils/schema-version.d.ts.map +1 -1
  144. package/dist/utils/schema-version.js +3 -1
  145. package/package.json +3 -3
  146. package/schema/entities.pl +6 -0
  147. package/src/public/impact/diagnostics.ts +29 -17
  148. package/src/public/operations/check-executor.ts +13 -0
  149. package/src/public/operations/contracts.ts +39 -2
  150. package/src/public/operations/decision-firmness.ts +280 -0
  151. package/src/public/operations/discovery-executors.ts +29 -4
  152. package/src/public/operations/migration-plan.ts +100 -19
  153. package/src/public/operations/result-envelope.ts +34 -1
  154. package/src/public/operations/specs/check-rules.generated.ts +6 -1
  155. package/src/public/operations/specs/mutation-schemas.ts +6 -0
  156. package/src/public/operations/specs/mutation.ts +7 -2
  157. package/src/public/operations/specs/planning.ts +2 -2
  158. package/src/public/operations/symbol-granularity-check.ts +233 -0
  159. package/src/public/schemas/entity.ts +12 -0
  160. package/src/public/skills/kibi-traceability/SKILL.md +6 -4
  161. package/src/public/skills/kibi-usage/SKILL.md +50 -10
  162. package/src/public/skills/kibi-usage/resources/source-authoring.md +4 -2
  163. package/src/public/symbol-granularity.ts +37 -0
  164. package/src/schemas/entity.schema.json +28 -0
@@ -15,14 +15,13 @@
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, mkdirSync, readFileSync, renameSync, writeFileSync, } from "node:fs";
18
+ import { existsSync, mkdirSync, renameSync, writeFileSync, } from "node:fs";
19
19
  import * as path from "node:path";
20
- import { load as parseYAML } from "js-yaml";
21
20
  import { applySafeInventoryRederivations, planInventoryRederivation, } from "../operations/migration/inventory-rederive.js";
22
21
  import { applyOriginBackfill, planOriginBackfill, } from "../operations/migration/origin-backfill.js";
23
22
  import { applySourcePathRepairs, findSourceRepairs, } from "../operations/migration/source-paths.js";
24
23
  import { applySupersededClosures, planSupersededClosures, } from "../operations/migration/superseded-closure.js";
25
- import { extractSymbolsFromStagedFile } from "../traceability/symbol-extract.js";
24
+ import { applySymbolLegacyLinks, planSymbolLegacyLinks, } from "../operations/migration/symbol-legacy-links.js";
26
25
  import { resolveBranchAttachment } from "../utils/branch-resolver.js";
27
26
  import { defaultKbManifest, readKbManifest, readKbManifestStatus, writeKbManifest, } from "../utils/kb-manifest.js";
28
27
  import { CANONICAL_ENTITY_PATHS } from "../utils/kb-paths.js";
@@ -79,6 +78,12 @@ const SCHEMA_MIGRATION_STEPS = [
79
78
  to: 8,
80
79
  description: "Pin semantic_text on requirements that lack it (computed from the body before context sections stop counting), and tag current entities without body context review:context-missing; front matter only, bodies are preserved.",
81
80
  },
81
+ {
82
+ id: "decision-firmness-v9",
83
+ from: 8,
84
+ to: 9,
85
+ description: "Accept firmness on requirements and ADRs, and acknowledge in the manifest the current supersedes recorded without a 'Why this changed' section; no source file is rewritten and no reason is invented.",
86
+ },
82
87
  ];
83
88
  function migrationStepsFor(fromVersion) {
84
89
  const start = Math.max(0, fromVersion ?? 0);
@@ -155,137 +160,25 @@ function normalizeSemanticAdvisorBackfill(value) {
155
160
  ? value
156
161
  : null;
157
162
  }
158
- const TRACEABILITY_RELATIONSHIP_TYPES = new Set([
159
- "implements",
160
- "covered_by",
161
- "executable_for",
162
- ]);
163
- function hasTraceabilityRelationship(symbol) {
164
- if (Array.isArray(symbol.links) && symbol.links.length > 0) {
165
- return true;
166
- }
167
- if (!Array.isArray(symbol.relationships)) {
168
- return false;
169
- }
170
- return symbol.relationships.some((relationship) => {
171
- if (relationship === null ||
172
- typeof relationship !== "object" ||
173
- Array.isArray(relationship)) {
174
- return false;
175
- }
176
- const type = relationship.type;
177
- return (typeof type === "string" && TRACEABILITY_RELATIONSHIP_TYPES.has(type));
178
- });
179
- }
180
- function getGranularNames(cwd, sourceFile) {
181
- const absolutePath = path.isAbsolute(sourceFile)
182
- ? sourceFile
183
- : path.join(cwd, sourceFile);
184
- if (!existsSync(absolutePath)) {
185
- return new Set();
186
- }
187
- const symbols = extractSymbolsFromStagedFile({
188
- path: sourceFile,
189
- status: "M",
190
- hunkRanges: [{ start: 1, end: Number.MAX_SAFE_INTEGER }],
191
- content: readFileSync(absolutePath, "utf8"),
192
- });
193
- return new Set(symbols.map((symbol) => symbol.name));
194
- }
195
- function addLegacyReasonsToManifestText(content, symbolIds) {
196
- if (symbolIds.size === 0)
197
- return content;
198
- const lines = content.split("\n");
199
- const output = [];
200
- let activeId = null;
201
- let activeHasReason = false;
202
- let activePropertyIndent = "";
203
- const flushLegacyReason = () => {
204
- if (activeId !== null &&
205
- symbolIds.has(activeId) &&
206
- !activeHasReason &&
207
- activePropertyIndent.length > 0) {
208
- output.push(`${activePropertyIndent}granularity_reason: legacy-link`);
209
- activeHasReason = true;
210
- }
211
- };
212
- for (const line of lines) {
213
- const idMatch = line.match(/^(\s*)-\s+id:\s+(.+)\s*$/);
214
- if (idMatch) {
215
- flushLegacyReason();
216
- activeId = idMatch[2]?.trim() ?? null;
217
- activeHasReason = false;
218
- activePropertyIndent = `${idMatch[1] ?? ""} `;
219
- }
220
- if (activeId !== null && /^\s+granularity_reason:\s+/.test(line)) {
221
- activeHasReason = true;
222
- }
223
- if (activeId !== null &&
224
- symbolIds.has(activeId) &&
225
- !activeHasReason &&
226
- /^\s+status:\s+/.test(line)) {
227
- const indent = line.match(/^\s*/)?.[0] ?? "";
228
- output.push(`${indent}granularity_reason: legacy-link`);
229
- activeHasReason = true;
230
- }
231
- output.push(line);
232
- }
233
- flushLegacyReason();
234
- return output.join("\n");
235
- }
236
- function migrateSymbolGranularity(options) {
237
- const manifestPath = options.manifestPath ??
238
- path.join(options.cwd, CANONICAL_ENTITY_PATHS.symbols);
239
- if (!existsSync(manifestPath)) {
240
- return { count: 0, manifestPath };
241
- }
242
- const manifestContent = readFileSync(manifestPath, "utf8");
243
- const parsed = parseYAML(manifestContent);
244
- if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
245
- return { count: 0, manifestPath };
246
- }
247
- const manifest = parsed;
248
- if (!Array.isArray(manifest.symbols)) {
249
- return { count: 0, manifestPath };
250
- }
251
- let count = 0;
252
- const migratedSymbolIds = new Set();
253
- const granularNamesByFile = new Map();
254
- for (const symbol of manifest.symbols) {
255
- if (symbol === null ||
256
- typeof symbol !== "object" ||
257
- Array.isArray(symbol)) {
258
- continue;
259
- }
260
- const record = symbol;
261
- if (typeof record.sourceFile !== "string")
262
- continue;
263
- if (typeof record.title !== "string")
264
- continue;
265
- if (typeof record.id !== "string")
266
- continue;
267
- if (record.granularity_reason !== undefined)
268
- continue;
269
- if (!hasTraceabilityRelationship(record))
270
- continue;
271
- let granularNames = granularNamesByFile.get(record.sourceFile);
272
- if (granularNames === undefined) {
273
- granularNames = getGranularNames(options.cwd, record.sourceFile);
274
- granularNamesByFile.set(record.sourceFile, granularNames);
275
- }
276
- if (granularNames.size === 0 || granularNames.has(record.title)) {
277
- continue;
278
- }
279
- count += 1;
280
- if (!options.dryRun) {
281
- record.granularity_reason = "legacy-link";
282
- migratedSymbolIds.add(record.id);
283
- }
284
- }
285
- if (count > 0 && !options.dryRun) {
286
- writeTextAtomically(manifestPath, addLegacyReasonsToManifestText(manifestContent, migratedSymbolIds));
287
- }
288
- return { count, manifestPath };
163
+ /**
164
+ * Mark the coarse symbol links the staged granularity gate would block as
165
+ * legacy-link. Runs at any schema version: the rule can call a link coarse
166
+ * that an older run (or a KB that skipped the schema 2 step) left unmarked.
167
+ */
168
+ // implements REQ-cli-schema-migration, REQ-symbol-behavioral-anchors
169
+ function markLegacySymbolLinks(cwd, dryRun, manifestPath) {
170
+ if (dryRun) {
171
+ const count = planSymbolLegacyLinks(cwd, manifestPath).targets.length;
172
+ if (count > 0)
173
+ console.log(`dry run: would mark ${count} coarse symbol link(s) as legacy-link (granularity_reason), so the staged check accepts them.`);
174
+ return count;
175
+ }
176
+ const { marked, unmarked } = applySymbolLegacyLinks(cwd);
177
+ if (marked.length > 0)
178
+ console.log(`Marked ${marked.length} existing coarse symbol link(s) as legacy-link.`);
179
+ if (unmarked.length > 0)
180
+ printWarning(`Could not mark ${unmarked.join(", ")} as legacy-link in place; add granularity_reason: legacy-link to them in ${CANONICAL_ENTITY_PATHS.symbols} by hand.`);
181
+ return marked.length;
289
182
  }
290
183
  function describeRederivation(plan) {
291
184
  const { keptModeled, roleChanges, newlyUnresolved, downgradedModeled } = plan.summary;
@@ -293,7 +186,7 @@ function describeRederivation(plan) {
293
186
  }
294
187
  function printManualRederivations(plans) {
295
188
  for (const plan of plans) {
296
- printWarning(`${plan.requirementId} (${plan.path}) no longer matches the current semantic advisor and needs a manual fix: ${plan.reasons.join("; ")}. Run 'kibi migrate --format json' for the exact repair steps.`);
189
+ printWarning(`${plan.requirementId} (${plan.path}) no longer matches the current semantic advisor and needs a manual fix: ${plan.reasons.join("; ")}. Run 'kibi migrate --format json' for the exact repair steps.${plan.rederivableByDroppingGrounding ? ` Or approve semantic-inventory-rederive-drop-grounding-${plan.requirementId} with --apply-safe --approved-action to drop the ${plan.orphanedGrounding.length} orphaned grounding link(s).` : ""}`);
297
190
  }
298
191
  }
299
192
  /**
@@ -421,9 +314,13 @@ export async function migrateCommand(options = {}) {
421
314
  }
422
315
  const manifestStatus = readKbManifestStatus(cwd);
423
316
  const storagePlan = planLegacyStorageMigration(cwd);
424
- // Baseline for fresh workspaces driven by the internal plan executor.
317
+ // Baseline for fresh workspaces driven by the internal plan executor. A
318
+ // legacy layout carries its own schema generation; a baseline would claim
319
+ // the latest one and skip every legacy step.
425
320
  if (options.initializeMissingConfig === true &&
426
- manifestStatus.state === "missing") {
321
+ manifestStatus.state === "missing" &&
322
+ storagePlan.moves.length === 0 &&
323
+ storagePlan.legacyConfig === "absent") {
427
324
  writeKbManifest(cwd, defaultKbManifest());
428
325
  }
429
326
  if (manifestStatus.state === "missing" &&
@@ -435,12 +332,19 @@ export async function migrateCommand(options = {}) {
435
332
  const { branch, warnings: branchWarnings } = branchResult;
436
333
  const currentManifest = readKbManifest(cwd);
437
334
  const legacySchemaVersion = normalizeSchemaVersion(storagePlan.schemaVersion);
438
- const currentVersion = currentManifest?.schemaVersion ?? legacySchemaVersion;
335
+ // While a legacy config is still present, its schemaVersion is the
336
+ // generation the knowledge was written for; a manifest created beside it
337
+ // (by an older 'kibi init') must not skip the steps in between.
338
+ const currentVersion = storagePlan.legacyConfig !== "absent" && legacySchemaVersion !== null
339
+ ? Math.min(currentManifest?.schemaVersion ?? legacySchemaVersion, legacySchemaVersion)
340
+ : (currentManifest?.schemaVersion ?? legacySchemaVersion);
439
341
  const normalizedVersion = normalizeSchemaVersion(currentVersion);
440
342
  const configStatus = getSchemaVersionStatus(normalizedVersion === null
441
343
  ? undefined
442
344
  : { schemaVersion: normalizedVersion });
443
- const needsStorageMigration = storagePlan.moves.length > 0 || storagePlan.legacyConfig !== "absent";
345
+ const needsStorageMigration = storagePlan.moves.length > 0 ||
346
+ storagePlan.removals.length > 0 ||
347
+ storagePlan.legacyConfig !== "absent";
444
348
  const needsSchemaUpgrade = configStatus.needsMigration || normalizedVersion === null;
445
349
  const migrationWarning = manifestStatus.state === "invalid" || manifestStatus.state === "future"
446
350
  ? manifestStatus.warning
@@ -473,7 +377,9 @@ export async function migrateCommand(options = {}) {
473
377
  // and lifecycle findings block kibi check at any version.
474
378
  const drift = rederiveDriftedInventories(cwd, options.dryRun === true);
475
379
  const lifecycle = repairLifecycleFindings(cwd, options.dryRun === true);
380
+ const legacyLinks = markLegacySymbolLinks(cwd, options.dryRun === true);
476
381
  const rewroteSources = polarityCount > 0 ||
382
+ legacyLinks > 0 ||
477
383
  drift.rederived.length > 0 ||
478
384
  lifecycle.closed > 0 ||
479
385
  lifecycle.rewritten > 0 ||
@@ -497,12 +403,13 @@ export async function migrateCommand(options = {}) {
497
403
  }
498
404
  const fromVersionLabel = formatSchemaVersion(currentVersion, normalizedVersion);
499
405
  const migrationSteps = migrationStepsFor(configStatus.currentVersion);
500
- const symbolGranularityStep = migrationSteps.some((step) => step.id === "symbol-granularity-v2");
501
406
  const semanticBackfillStep = migrationSteps.some((step) => step.id === "semantic-backfill-v4");
502
407
  const originBackfillStep = migrationSteps.some((step) => step.id === "entity-origin-v6");
503
408
  const { planPolarityValueBackfill, applyPolarityValueBackfill } = await import("../operations/migration/polarity-values.js");
504
409
  const polarityBackfill = planPolarityValueBackfill(cwd);
505
410
  const bodyContextStep = migrationSteps.some((step) => step.id === "entity-body-context-v8");
411
+ const decisionFirmnessStep = migrationSteps.some((step) => step.id === "decision-firmness-v9");
412
+ const { mergeSupersedesAcknowledgements, planSupersedesReasonAcknowledgement, } = await import("../operations/migration/supersedes-reason.js");
506
413
  const { acknowledgedContextIds, applyContextMissingTags, applySemanticTextPins, countByType, planContextMissingTags, planSemanticTextPins, } = await import("../operations/migration/entity-body-context.js");
507
414
  if (options.dryRun) {
508
415
  if (polarityBackfill.length > 0)
@@ -519,27 +426,28 @@ export async function migrateCommand(options = {}) {
519
426
  for (const skip of [...pins.skipped, ...tags.skipped])
520
427
  printWarning(`Cannot edit ${skip.path}: ${skip.reason}.`);
521
428
  }
429
+ if (decisionFirmnessStep) {
430
+ const unexplained = planSupersedesReasonAcknowledgement(cwd);
431
+ if (unexplained.length > 0)
432
+ console.log(`dry run: would acknowledge ${unexplained.length} supersede(s) recorded without a 'Why this changed' section (manifest only; no reason is written).`);
433
+ }
522
434
  if (storagePlan.moves.length > 0) {
523
435
  console.log(`dry run: would move ${storagePlan.moves.length} legacy knowledge file(s) into .kb/:`);
524
436
  for (const move of storagePlan.moves) {
525
437
  console.log(` ${move.from} -> ${move.to}`);
526
438
  }
527
439
  }
440
+ if (storagePlan.removals.length > 0) {
441
+ console.log(`dry run: would remove ${storagePlan.removals.length} legacy cop(ies) identical to their .kb/ file:`);
442
+ for (const removal of storagePlan.removals) {
443
+ console.log(` ${removal.path} (same as ${removal.duplicateOf})`);
444
+ }
445
+ }
528
446
  if (storagePlan.legacyConfig !== "absent") {
529
447
  console.log("dry run: would retire legacy .kb/config.json after moving knowledge into .kb/.");
530
448
  }
531
449
  console.log(`dry run: would set schemaVersion from ${fromVersionLabel} to ${LATEST_KB_SCHEMA_VERSION} in .kb/manifest.json.`);
532
- if (symbolGranularityStep) {
533
- const symbolsSource = storagePlan.moves.find((move) => move.to === CANONICAL_ENTITY_PATHS.symbols)?.from ?? CANONICAL_ENTITY_PATHS.symbols;
534
- const preview = migrateSymbolGranularity({
535
- cwd,
536
- dryRun: true,
537
- manifestPath: path.join(cwd, symbolsSource),
538
- });
539
- if (preview.count > 0) {
540
- console.log(`dry run: would mark ${preview.count} legacy coarse symbol link(s) as legacy-link.`);
541
- }
542
- }
450
+ markLegacySymbolLinks(cwd, true, storagePlan.moves.find((move) => move.to === CANONICAL_ENTITY_PATHS.symbols)?.from);
543
451
  if (originBackfillStep) {
544
452
  const backfill = planOriginBackfill(cwd);
545
453
  if (backfill.targets.length > 0) {
@@ -558,17 +466,18 @@ export async function migrateCommand(options = {}) {
558
466
  const storageResult = applyLegacyStorageMigration(cwd, storagePlan);
559
467
  if (storageResult.movedFiles.length > 0) {
560
468
  console.log(`Moved ${storageResult.movedFiles.length} knowledge file(s) into the canonical .kb/ layout.`);
469
+ const untracked = storageResult.untrackedMovedFiles.length;
470
+ if (untracked > 0)
471
+ printWarning(`${untracked} moved file(s) are not tracked by Git yet. Kibi recorded a pending-source receipt for each, so kibi sync compiles them now; stage them before you commit (git add .kb, plus the removals under the legacy folders). Each receipt retires once Git tracks its file.`);
472
+ }
473
+ if (storageResult.removedFiles.length > 0) {
474
+ console.log(`Removed ${storageResult.removedFiles.length} legacy cop(ies) identical to their .kb/ file: ${storageResult.removedFiles.join(", ")}.`);
561
475
  }
562
476
  if (storageResult.retiredLegacyConfig) {
563
477
  console.log("Retired legacy .kb/config.json.");
564
478
  }
565
479
  }
566
- const symbolGranularityMigration = symbolGranularityStep
567
- ? migrateSymbolGranularity({
568
- cwd,
569
- dryRun: options.yes !== true,
570
- })
571
- : { count: 0 };
480
+ const legacyLinksMarked = markLegacySymbolLinks(cwd, false);
572
481
  const semanticAdvisorBackfill = normalizeSemanticAdvisorBackfill(readKbManifest(cwd)?.semanticAdvisorBackfill) ??
573
482
  normalizeSemanticAdvisorBackfill(storagePlan.semanticAdvisorBackfill) ??
574
483
  (semanticBackfillStep || needsStorageMigration
@@ -599,6 +508,9 @@ export async function migrateCommand(options = {}) {
599
508
  : { written: [], skipped: [], previouslyStamped: 0 };
600
509
  rederiveDriftedInventories(cwd, false);
601
510
  const lifecycle = repairLifecycleFindings(cwd, false);
511
+ const supersedesUnexplained = decisionFirmnessStep
512
+ ? planSupersedesReasonAcknowledgement(cwd)
513
+ : [];
602
514
  const existingManifest = readKbManifest(cwd) ?? defaultKbManifest();
603
515
  writeKbManifest(cwd, {
604
516
  ...existingManifest,
@@ -614,14 +526,21 @@ export async function migrateCommand(options = {}) {
614
526
  ].sort(),
615
527
  }
616
528
  : {}),
529
+ ...(supersedesUnexplained.length > 0
530
+ ? {
531
+ supersedesReasonAcknowledged: mergeSupersedesAcknowledgements(existingManifest.supersedesReasonAcknowledged, supersedesUnexplained),
532
+ }
533
+ : {}),
617
534
  });
535
+ if (supersedesUnexplained.length > 0)
536
+ console.log(`Acknowledged ${supersedesUnexplained.length} supersede(s) recorded without a 'Why this changed' section; new supersedes must explain themselves.`);
618
537
  writeJsonAtomically(auditPath, buildMigrationAuditRecord({
619
538
  branch,
620
539
  manifestPath: KB_MANIFEST_RELATIVE,
621
540
  fromVersion: configStatus.currentVersion,
622
541
  migratedAt,
623
542
  semanticAdvisorBackfill,
624
- symbolGranularityLegacyLinks: symbolGranularityMigration.count,
543
+ symbolGranularityLegacyLinks: legacyLinksMarked,
625
544
  entityOriginBackfill: originBackfill.written.length + originBackfill.previouslyStamped,
626
545
  supersededRequirementsClosed: lifecycle.closed,
627
546
  sourcePathsRewritten: lifecycle.rewritten,
@@ -630,9 +549,6 @@ export async function migrateCommand(options = {}) {
630
549
  steps: migrationSteps.map((step) => step.id),
631
550
  }));
632
551
  console.log(`Migrated the KB to schemaVersion ${LATEST_KB_SCHEMA_VERSION} on the canonical .kb/ layout (was ${fromVersionLabel}).`);
633
- if (symbolGranularityMigration.count > 0) {
634
- console.log(`Marked ${symbolGranularityMigration.count} existing coarse symbol link(s) as legacy-link.`);
635
- }
636
552
  if (semanticAdvisorBackfill === "pending") {
637
553
  console.log(`Marked semantic advisor backfill as pending in ${KB_MANIFEST_RELATIVE}.`);
638
554
  }
@@ -714,9 +630,13 @@ async function buildWorkspaceMigrationPlan(workspaceRoot = process.cwd()) {
714
630
  if (checkable && storeSynced) {
715
631
  const checkResult = await executeOperation(runtime, checkSpec, {});
716
632
  if (checkResult.structuredContent?.migrationPlan !== undefined) {
717
- // Lifecycle repairs and their sync are planned above from authored
718
- // sources, which may be newer than the compiled store.
719
- plans.push(withoutActionCodes(checkResult.structuredContent.migrationPlan, SOURCE_PLANNED_LIFECYCLE_CODES));
633
+ // Lifecycle repairs, their sync and requirement status mappings are
634
+ // planned above from authored sources, which may be newer than the
635
+ // compiled store.
636
+ plans.push(withoutActionCodes(checkResult.structuredContent.migrationPlan, new Set([
637
+ ...SOURCE_PLANNED_LIFECYCLE_CODES,
638
+ "check_req-status-vocabulary",
639
+ ])));
720
640
  }
721
641
  const coverageInputs = [
722
642
  { by: "req", limit: 10_000, offset: 0 },
@@ -759,7 +679,53 @@ async function buildWorkspaceMigrationPlan(workspaceRoot = process.cwd()) {
759
679
  ],
760
680
  });
761
681
  }
762
- return mergeMigrationPlans(plans);
682
+ return orderStoreSyncAfterSourceRewrites({ buildMigrationPlan, migrationAction }, mergeMigrationPlans(plans), fragment.sourceRewriteActionIds, fragment.actions
683
+ .filter((action) => action.code === "semantic_inventory_review")
684
+ .map((action) => action.id));
685
+ }
686
+ /** Status actions that run 'kibi sync' over the authored sources. */
687
+ const STORE_SYNC_ACTION_IDS = new Set([
688
+ "branch-store-compile",
689
+ "freshness-resync",
690
+ ]);
691
+ /**
692
+ * A sync compiles the authored sources, so it must run after the source
693
+ * rewrites that make them ingestible. While a requirement still needs a
694
+ * manual inventory review the sync would fail on it, so it waits on that
695
+ * review just as the migration sync does.
696
+ */
697
+ // implements REQ-cli-schema-migration
698
+ function orderStoreSyncAfterSourceRewrites(builders, plan, rewriteActionIds, reviewActionIds) {
699
+ const affected = plan.actions.some((action) => STORE_SYNC_ACTION_IDS.has(action.id) && action.state === "ready");
700
+ if (!affected ||
701
+ (rewriteActionIds.length === 0 && reviewActionIds.length === 0))
702
+ return plan;
703
+ const actions = plan.actions.map((action) => {
704
+ if (!STORE_SYNC_ACTION_IDS.has(action.id) || action.state !== "ready")
705
+ return action;
706
+ if (reviewActionIds.length > 0)
707
+ return builders.migrationAction({
708
+ ...action,
709
+ state: "blocked",
710
+ autoApplicable: false,
711
+ evidence: {
712
+ ...action.evidence,
713
+ blockedBy: [...reviewActionIds],
714
+ reason: "kibi sync rejects a requirement until its semantic inventory review is fixed; rerun kibi migrate afterwards.",
715
+ },
716
+ });
717
+ return builders.migrationAction({
718
+ ...action,
719
+ dependsOn: [...action.dependsOn, ...rewriteActionIds],
720
+ });
721
+ });
722
+ return builders.buildMigrationPlan({
723
+ expected: plan.expected,
724
+ evaluatedDomains: plan.scope.evaluatedDomains,
725
+ incompleteDomains: plan.scope.incompleteDomains,
726
+ actions,
727
+ diagnostics: plan.diagnostics,
728
+ });
763
729
  }
764
730
  /**
765
731
  * The action ids approved on the command line. The CLI parser stores
@@ -776,6 +742,24 @@ function approvedActionIdsOf(options) {
776
742
  .filter((id) => id.length > 0);
777
743
  return [...new Set(ids)];
778
744
  }
745
+ /** The table rendering of an apply result; --format json prints it whole. */
746
+ // implements REQ-cli-schema-migration
747
+ function printApplySummary(content) {
748
+ if (content === null || typeof content !== "object")
749
+ return;
750
+ const result = content;
751
+ if (result.outcome !== undefined)
752
+ console.log(`Outcome: ${result.outcome}`);
753
+ for (const action of result.actionResults ?? []) {
754
+ console.log(`- ${action.outcome} ${action.actionId}: ${action.detail}`);
755
+ }
756
+ const remaining = result.remainingPlan;
757
+ if (remaining !== undefined) {
758
+ const ready = remaining.actions.filter((action) => action.state === "ready" && action.autoApplicable).length;
759
+ console.log(`Remaining plan ${remaining.planHash}: ${remaining.status}; actions: ${remaining.summary.actionCount}; automatic-ready: ${ready}`);
760
+ }
761
+ console.log("Run 'kibi migrate' for the remaining actions, or add --format json for the full result.");
762
+ }
779
763
  async function migratePlanCommand(options) {
780
764
  const workspaceRoot = path.resolve(options.workspaceRoot ?? process.cwd());
781
765
  const plan = await buildWorkspaceMigrationPlan(workspaceRoot);
@@ -830,7 +814,7 @@ async function migratePlanCommand(options) {
830
814
  }
831
815
  else {
832
816
  console.log(result.content[0]?.text ?? "Migration applied.");
833
- console.log(JSON.stringify(result.structuredContent, null, 2));
817
+ printApplySummary(result.structuredContent);
834
818
  }
835
819
  return {
836
820
  exitCode: result.structuredContent?.outcome === "applied" ? 0 : 1,
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/manifest.ts"],"names":[],"mappings":"AAkBA,OAAO,EACL,UAAU,EACV,YAAY,EACZ,UAAU,EACV,UAAU,EACV,aAAa,EACd,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,SAAS,CAAC;AAE9D,OAAO,EAML,uBAAuB,EACxB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,KAAK,mBAAmB,EACxB,uBAAuB,EACxB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EACL,0BAA0B,EAG3B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAG5E,UAAU,YAAY;IACpB,QAAQ,EAAE,OAAO,QAAQ,CAAC;IAC1B,uBAAuB,EAAE,OAAO,uBAAuB,CAAC;IACxD,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,aAAa,EAAE,OAAO,aAAa,CAAC;IACpC,uBAAuB,EAAE,OAAO,uBAAuB,CAAC;IACxD,2BAA2B,EAAE,OAAO,2BAA2B,CAAC;CACjE;AAkBD,eAAO,MAAM,8BAA8B,QAc1C,CAAC;AAaF;;;;;;;;;GASG;AACH,OAAO,EAAE,0BAA0B,EAAE,CAAC;AAEtC,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAG7E;AAoHD,wBAAsB,0BAA0B,CAE9C,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG;IAC7B,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GACA,OAAO,CAAC,IAAI,CAAC,CA0Mf;AAED;;;;;;;;GAQG;AAEH,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAC3B,MAAM,GAAG,IAAI,CAWf;AAED,wBAAgB,0BAA0B,CAExC,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAOT;AAED,wBAAgB,8BAA8B,CAE5C,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAC3B,OAAO,CAUT"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/manifest.ts"],"names":[],"mappings":"AAkBA,OAAO,EACL,UAAU,EACV,YAAY,EACZ,UAAU,EACV,UAAU,EACV,aAAa,EACd,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,SAAS,CAAC;AAE9D,OAAO,EAML,uBAAuB,EACxB,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,KAAK,mBAAmB,EACxB,uBAAuB,EACxB,MAAM,yCAAyC,CAAC;AACjD,OAAO,EACL,0BAA0B,EAG3B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAG5E,UAAU,YAAY;IACpB,QAAQ,EAAE,OAAO,QAAQ,CAAC;IAC1B,uBAAuB,EAAE,OAAO,uBAAuB,CAAC;IACxD,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,aAAa,EAAE,OAAO,aAAa,CAAC;IACpC,uBAAuB,EAAE,OAAO,uBAAuB,CAAC;IACxD,2BAA2B,EAAE,OAAO,2BAA2B,CAAC;CACjE;AAkBD,eAAO,MAAM,8BAA8B,QAc1C,CAAC;AAeF;;;;;;;;;GASG;AACH,OAAO,EAAE,0BAA0B,EAAE,CAAC;AAEtC,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAG7E;AA2HD,wBAAsB,0BAA0B,CAE9C,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG;IAC7B,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,GACA,OAAO,CAAC,IAAI,CAAC,CA0Mf;AAED;;;;;;;;GAQG;AAEH,wBAAgB,uBAAuB,CACrC,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAC3B,MAAM,GAAG,IAAI,CAWf;AAED,wBAAgB,0BAA0B,CAExC,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAOT;AAED,wBAAgB,8BAA8B,CAE5C,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAC3B,OAAO,CAUT"}
@@ -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`;
@@ -1 +1 @@
1
- {"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/persistence.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAEV,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA2HrD,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;CACrB;AAuFD,iFAAiF;AACjF,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,aAAa,EACrB,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,OAAO,CAAC,MAAM,CAAC,CA+BjB;AAED,0EAA0E;AAC1E,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,OAAO,CAAC,MAAM,CAAC,CAmBjB;AAED,8EAA8E;AAC9E,wBAAsB,8BAA8B,CAClD,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,aAAa,EAAE,SAAS,qBAAqB,EAAE,GAC9C,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAmCD,wBAAsB,eAAe,CAEnC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,EACtB,OAAO,GAAE;IAAE,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAAO,GAChD,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CA8QvD;AA4BD,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,MAAM,CAER;AAGD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,kBAAkB,EAAE,qBAAqB,EAAE,EAC3C,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GACvC,OAAO,CAAC;IAAE,iBAAiB,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CAmO7D"}
1
+ {"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/persistence.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAEV,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA2HrD,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;CACrB;AAuFD,iFAAiF;AACjF,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,aAAa,EACrB,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,OAAO,CAAC,MAAM,CAAC,CA+BjB;AAED,0EAA0E;AAC1E,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,OAAO,CAAC,MAAM,CAAC,CAmBjB;AAED,8EAA8E;AAC9E,wBAAsB,8BAA8B,CAClD,MAAM,EAAE,aAAa,EACrB,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,aAAa,EAAE,SAAS,qBAAqB,EAAE,GAC9C,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAmCD,wBAAsB,eAAe,CAEnC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,EACtB,OAAO,GAAE;IAAE,qBAAqB,CAAC,EAAE,OAAO,CAAA;CAAO,GAChD,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CAoRvD;AA4BD,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,MAAM,CAER;AAGD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,kBAAkB,EAAE,qBAAqB,EAAE,EAC3C,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,MAAM,CAAA;CAAO,GACvC,OAAO,CAAC;IAAE,iBAAiB,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CAmO7D"}
@@ -377,6 +377,10 @@ prolog, results, entityIds, options = {}) {
377
377
  if (entity.type === "req" && entity.proof_exempt !== undefined) {
378
378
  props.push(`proof_exempt=${entity.proof_exempt}`);
379
379
  }
380
+ if ((entity.type === "req" || entity.type === "adr") &&
381
+ entity.firmness !== undefined) {
382
+ props.push(`firmness=${toPrologAtom(entity.firmness)}`);
383
+ }
380
384
  if (entity.type === "scenario" && entity.expects !== undefined) {
381
385
  props.push(`expects=${toPrologAtom(entity.expects)}`);
382
386
  }
@@ -0,0 +1,39 @@
1
+ /** Firmness values, firmest first. */
2
+ export declare const FIRMNESS_VALUES: readonly ["firm", "default", "exploratory"];
3
+ export type Firmness = (typeof FIRMNESS_VALUES)[number];
4
+ /** The firmness of a decision that does not state one. */
5
+ export declare const DEFAULT_FIRMNESS: Firmness;
6
+ /** Entity types that carry firmness. */
7
+ export declare const FIRMNESS_TYPES: readonly ["req", "adr"];
8
+ /** A supersede must explain itself under a heading starting with this. */
9
+ export declare const WHY_THIS_CHANGED_HEADING = "Why this changed";
10
+ /** The explanation needs at least this many words of prose. */
11
+ export declare const MIN_WHY_CHANGED_WORDS = 12;
12
+ /**
13
+ * How the manifest records one acknowledged supersede edge. Edges, not ids,
14
+ * are acknowledged, so a supersede added later to the same entity still has
15
+ * to explain itself.
16
+ */
17
+ export declare function supersedeAcknowledgement(from: string, to: string): string;
18
+ export declare function isFirmness(value: unknown): value is Firmness;
19
+ export declare function carriesFirmness(type: unknown): boolean;
20
+ /**
21
+ * The firmness a decision is read with: the authored value, else `default`.
22
+ * Undefined for types that carry no firmness.
23
+ */
24
+ export declare function effectiveFirmness(type: unknown, value: unknown): Firmness | undefined;
25
+ /**
26
+ * The reference that makes a firm decision traceable to a human's words:
27
+ * `origin.ref`, or `approval_ref` on a requirement.
28
+ */
29
+ export declare function firmnessRef(entity: {
30
+ type?: unknown;
31
+ origin?: unknown;
32
+ approval_ref?: unknown;
33
+ }): string | undefined;
34
+ /**
35
+ * Words of prose under the body's "Why this changed" heading (nested
36
+ * headings included), or 0 when the body has no such section.
37
+ */
38
+ export declare function whyThisChangedWords(body: string): number;
39
+ //# sourceMappingURL=decision-firmness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision-firmness.d.ts","sourceRoot":"","sources":["../src/decision-firmness.ts"],"names":[],"mappings":"AA4BA,sCAAsC;AAEtC,eAAO,MAAM,eAAe,6CAA8C,CAAC;AAG3E,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AAExD,0DAA0D;AAE1D,eAAO,MAAM,gBAAgB,EAAE,QAAoB,CAAC;AAEpD,wCAAwC;AAExC,eAAO,MAAM,cAAc,yBAA0B,CAAC;AAEtD,0EAA0E;AAE1E,eAAO,MAAM,wBAAwB,qBAAqB,CAAC;AAE3D,+DAA+D;AAE/D,eAAO,MAAM,qBAAqB,KAAK,CAAC;AAIxC;;;;GAIG;AAEH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAEzE;AAGD,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAK5D;AAGD,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAKtD;AAED;;;GAGG;AAEH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,OAAO,GACb,QAAQ,GAAG,SAAS,CAGtB;AAED;;;GAGG;AAEH,wBAAgB,WAAW,CAAC,MAAM,EAAE;IAClC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,GAAG,MAAM,GAAG,SAAS,CAcrB;AAMD;;;GAGG;AAEH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAkBxD"}