kibi-cli 2.22.0 → 2.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/commands/doctor.d.ts.map +1 -1
  2. package/dist/commands/doctor.js +12 -0
  3. package/dist/commands/init-helpers.d.ts +2 -1
  4. package/dist/commands/init-helpers.d.ts.map +1 -1
  5. package/dist/commands/init-helpers.js +3 -0
  6. package/dist/commands/migrate.d.ts +37 -0
  7. package/dist/commands/migrate.d.ts.map +1 -1
  8. package/dist/commands/migrate.js +24 -6
  9. package/dist/operations/mutation/validation.d.ts.map +1 -1
  10. package/dist/operations/mutation/validation.js +43 -1
  11. package/dist/operations/planning/apply-plan.d.ts.map +1 -1
  12. package/dist/operations/planning/apply-plan.js +16 -7
  13. package/dist/operations/semantic-advisor/ingestion-boundary.d.ts.map +1 -1
  14. package/dist/operations/semantic-advisor/ingestion-boundary.js +25 -1
  15. package/dist/operations/semantic-advisor/stored-ledger-drift.d.ts +19 -0
  16. package/dist/operations/semantic-advisor/stored-ledger-drift.d.ts.map +1 -0
  17. package/dist/operations/semantic-advisor/stored-ledger-drift.js +78 -0
  18. package/dist/public/operations/decision-firmness.d.ts +3 -1
  19. package/dist/public/operations/decision-firmness.d.ts.map +1 -1
  20. package/dist/public/operations/decision-firmness.js +13 -3
  21. package/dist/public/operations/discovery-executors.d.ts.map +1 -1
  22. package/dist/public/operations/discovery-executors.js +15 -0
  23. package/dist/public/operations/migration-plan.d.ts +13 -0
  24. package/dist/public/operations/migration-plan.d.ts.map +1 -1
  25. package/dist/public/operations/migration-plan.js +29 -1
  26. package/dist/public/operations/specs/semantic.d.ts.map +1 -1
  27. package/dist/public/operations/specs/semantic.js +26 -1
  28. package/dist/public/skills/kibi-usage/SKILL.md +8 -3
  29. package/package.json +1 -1
  30. package/src/public/operations/decision-firmness.ts +18 -2
  31. package/src/public/operations/discovery-executors.ts +16 -0
  32. package/src/public/operations/migration-plan.ts +47 -1
  33. package/src/public/operations/specs/semantic.ts +37 -2
  34. package/src/public/skills/kibi-usage/SKILL.md +8 -3
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAgGA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAC3B;AAGD,wBAAsB,aAAa,CACjC,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAmH/B;AAED,wBAAsB,4BAA4B,CAChD,IAAI,GAAE,MAAM,OAAO,CAAC;IAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAE,CACT,GACxC,OAAO,CAAC,OAAO,CAAC,CAOlB;AAED,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;;;;;;;;;;;;;;;;MAkE3C;AAkGD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGzE;AAED,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CAepB"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAiGA,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAC3B;AAGD,wBAAsB,aAAa,CACjC,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAmH/B;AAED,wBAAsB,4BAA4B,CAChD,IAAI,GAAE,MAAM,OAAO,CAAC;IAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;CAAE,CACT,GACxC,OAAO,CAAC,OAAO,CAAC,CAOlB;AAED,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;;;;;;;;;;;;;;;;MAkE3C;AAkGD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGzE;AAED,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,MAAM,GAAG,SAAS,CAepB"}
@@ -29,6 +29,7 @@ import { resolveBranchAttachment, resolveReadBranchAttachment, } from "../utils/
29
29
  import { branchStoreCompilation, inspectBranchStore, storeLockTakeoverReason, uncompiledBranchStoreReason, } from "../utils/branch-store.js";
30
30
  import { resolveGitRepository, } from "../utils/git-repository-context.js";
31
31
  import { readKbManifestStatus } from "../utils/kb-manifest.js";
32
+ import { LATEST_KB_SCHEMA_VERSION } from "../utils/schema-version.js";
32
33
  import { KIBI_HOOK_BEGIN, hasManagedHooks, outdatedManagedHooks, } from "./init-helpers.js";
33
34
  import { planLegacyStorageMigration } from "./legacy-storage-migration.js";
34
35
  /**
@@ -616,6 +617,17 @@ function checkKbManifest() {
616
617
  remediation: `Repair .kb/manifest.json: ${status.warning}`,
617
618
  };
618
619
  }
620
+ // A knowledge base written by an older Kibi keeps reading and checking
621
+ // until migrated, but the current CLI expects its own schema: say so here,
622
+ // where the operator looks first, instead of leaving it to the next
623
+ // failing check. The migration plan below names the actions.
624
+ if (status.manifest.schemaVersion < LATEST_KB_SCHEMA_VERSION) {
625
+ return {
626
+ passed: false,
627
+ message: `schemaVersion ${status.manifest.schemaVersion} (this Kibi expects ${LATEST_KB_SCHEMA_VERSION})`,
628
+ remediation: "Run: kibi migrate (previews the plan), then kibi migrate --yes to apply it, or kibi migrate --apply-safe --approved-plan-hash <planHash> --approved-action <id> for selected actions",
629
+ };
630
+ }
619
631
  return {
620
632
  passed: true,
621
633
  message: `schemaVersion ${status.manifest.schemaVersion}`,
@@ -1,7 +1,8 @@
1
1
  export declare function getCurrentBranch(cwd?: string): Promise<string>;
2
2
  export declare function createKbDirectoryStructure(kbDir: string, currentBranch: string): void;
3
3
  export declare function createManifestFile(kbDir: string): void;
4
- export declare function updateGitIgnore(cwd: string): void;
4
+ /** Adds the canonical derived entries to .gitignore; true when it changed the file. */
5
+ export declare function updateGitIgnore(cwd: string): boolean;
5
6
  export declare function ensureSymbolsManifestFile(cwd: string): void;
6
7
  export declare function copySchemaFiles(kbDir: string, schemaSourceDir: string): Promise<void>;
7
8
  export declare const KIBI_HOOK_BEGIN = "# BEGIN kibi-managed";
@@ -1 +1 @@
1
- {"version":3,"file":"init-helpers.d.ts","sourceRoot":"","sources":["../../src/commands/init-helpers.ts"],"names":[],"mappings":"AA6IA,wBAAsB,gBAAgB,CACpC,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,GACpB,IAAI,CA0BN;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAGtD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CA6BjD;AAkDD,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAU3D;AAED,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED,eAAO,MAAM,eAAe,yBAAyB,CAAC;AAOtD,MAAM,MAAM,iBAAiB,GACzB,WAAW,GACX,SAAS,GACT,iBAAiB,GACjB,iBAAiB,GACjB,qBAAqB,CAAC;AAE1B,wDAAwD;AACxD,eAAO,MAAM,kBAAkB,wEAKrB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAGlE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,eAAe,CAEzE;AAED;;;;;;GAMG;AAEH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAqBnE;AAkBD,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,iBAAiB,CAwEnB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,eAAe,CAAC;IACtB,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAiBD;;;;GAIG;AAEH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAU/D;AAED,wEAAwE;AAExE,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAQzD;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,GAChD,oBAAoB,EAAE,CA8CxB"}
1
+ {"version":3,"file":"init-helpers.d.ts","sourceRoot":"","sources":["../../src/commands/init-helpers.ts"],"names":[],"mappings":"AA6IA,wBAAsB,gBAAgB,CACpC,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,GACpB,IAAI,CA0BN;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAGtD;AAED,uFAAuF;AACvF,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CA+BpD;AAkDD,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAU3D;AAED,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED,eAAO,MAAM,eAAe,yBAAyB,CAAC;AAOtD,MAAM,MAAM,iBAAiB,GACzB,WAAW,GACX,SAAS,GACT,iBAAiB,GACjB,iBAAiB,GACjB,qBAAqB,CAAC;AAE1B,wDAAwD;AACxD,eAAO,MAAM,kBAAkB,wEAKrB,CAAC;AAEX,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAGlE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,eAAe,CAEzE;AAED;;;;;;GAMG;AAEH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAqBnE;AAkBD,wBAAgB,WAAW,CACzB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,iBAAiB,CAwEnB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,eAAe,CAAC;IACtB,MAAM,EAAE,iBAAiB,CAAC;CAC3B;AAiBD;;;;GAIG;AAEH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAU/D;AAED,wEAAwE;AAExE,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAQzD;AAED,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IAAE,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,GAChD,oBAAoB,EAAE,CA8CxB"}
@@ -155,6 +155,7 @@ export function createManifestFile(kbDir) {
155
155
  writeKbManifest(path.dirname(kbDir), defaultKbManifest());
156
156
  console.log("✓ Created Kibi lifecycle manifest at .kb/manifest.json");
157
157
  }
158
+ /** Adds the canonical derived entries to .gitignore; true when it changed the file. */
158
159
  export function updateGitIgnore(cwd) {
159
160
  // implements REQ-cli-init-canonical
160
161
  const gitignorePath = path.join(cwd, ".gitignore");
@@ -179,7 +180,9 @@ export function updateGitIgnore(cwd) {
179
180
  if (updatedContent !== gitignoreContent) {
180
181
  writeFileSync(gitignorePath, updatedContent);
181
182
  console.log("✓ Configured .gitignore for the canonical .kb/ layout");
183
+ return true;
182
184
  }
185
+ return false;
183
186
  }
184
187
  /** Exact derived-runtime entries owned by current Kibi init/migrate. */
185
188
  const CANONICAL_DERIVED_GITIGNORE_ENTRIES = [
@@ -11,12 +11,49 @@ interface MigrateOptions {
11
11
  /** Internal migration-plan executor: create only the canonical baseline manifest. */
12
12
  initializeMissingConfig?: boolean;
13
13
  }
14
+ export interface MigrationAuditRecord {
15
+ auditVersion: number;
16
+ branch: string;
17
+ manifestPath: string;
18
+ fromVersion: number | null;
19
+ migratedAt: string;
20
+ semanticAdvisorBackfill: "pending" | "completed" | "not_applicable" | null;
21
+ status: "applied";
22
+ symbolGranularityLegacyLinks: number;
23
+ /** Entities carrying origin {kind: migration, ref: 'kibi migrate v5->v6'}. */
24
+ entityOriginBackfill: number;
25
+ /** Superseded requirements this run set to status: closed. */
26
+ supersededRequirementsClosed: number;
27
+ /** Pre-canonical source paths this run pointed at their .kb/ file. */
28
+ sourcePathsRewritten: number;
29
+ /** Authored source values this run removed: they named the entity's own file or nothing. */
30
+ sourcePathsRemoved: number;
31
+ toVersion: number;
32
+ /** The schema warning the KB showed before this run migrated it. */
33
+ preMigrationWarning: string | null;
34
+ steps: readonly string[];
35
+ }
36
+ /** What one applied `kibi migrate --yes` run changed, for plan apply results. */
37
+ export interface MigrationRunSummary {
38
+ /** Workspace-relative path of the audit record this run wrote. */
39
+ auditPath: string;
40
+ audit: MigrationAuditRecord;
41
+ /** Whether this run added the canonical derived entries to .gitignore. */
42
+ gitignoreUpdated: boolean;
43
+ }
14
44
  export declare function formatSchemaVersion(rawSchemaVersion: unknown, normalized: number | null): string;
15
45
  export declare function warnMigrationRequiredWithoutYes(): {
16
46
  exitCode: number;
17
47
  };
18
48
  export declare function migrateCommand(options?: MigrateOptions): Promise<{
19
49
  exitCode: number;
50
+ summary?: MigrationRunSummary;
20
51
  }>;
52
+ /**
53
+ * One line naming what an applied migration run changed, read from the audit
54
+ * record it wrote: a count of zero shows a pass that had nothing left to do
55
+ * (for example legacy links an earlier plan action already marked).
56
+ */
57
+ export declare function describeMigrationRun(summary: MigrationRunSummary): string;
21
58
  export {};
22
59
  //# sourceMappingURL=migrate.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AAmEA,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,uFAAuF;IACvF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qFAAqF;IACrF,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AA+JD,wBAAgB,mBAAmB,CACjC,gBAAgB,EAAE,OAAO,EACzB,UAAU,EAAE,MAAM,GAAG,IAAI,GACxB,MAAM,CAUR;AAsOD,wBAAgB,+BAA+B,IAAI;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAKtE;AAGD,wBAAsB,cAAc,CAClC,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CA2Y/B"}
1
+ {"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AAmEA,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,uFAAuF;IACvF,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qFAAqF;IACrF,uBAAuB,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,uBAAuB,EAAE,SAAS,GAAG,WAAW,GAAG,gBAAgB,GAAG,IAAI,CAAC;IAC3E,MAAM,EAAE,SAAS,CAAC;IAClB,4BAA4B,EAAE,MAAM,CAAC;IACrC,8EAA8E;IAC9E,oBAAoB,EAAE,MAAM,CAAC;IAC7B,8DAA8D;IAC9D,4BAA4B,EAAE,MAAM,CAAC;IACrC,sEAAsE;IACtE,oBAAoB,EAAE,MAAM,CAAC;IAC7B,4FAA4F;IAC5F,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B;AAED,iFAAiF;AACjF,MAAM,WAAW,mBAAmB;IAClC,kEAAkE;IAClE,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,oBAAoB,CAAC;IAC5B,0EAA0E;IAC1E,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAyID,wBAAgB,mBAAmB,CACjC,gBAAgB,EAAE,OAAO,EACzB,UAAU,EAAE,MAAM,GAAG,IAAI,GACxB,MAAM,CAUR;AAsOD,wBAAgB,+BAA+B,IAAI;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAKtE;AAGD,wBAAsB,cAAc,CAClC,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,mBAAmB,CAAA;CAAE,CAAC,CAgZ9D;AAED;;;;GAIG;AAEH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAGzE"}
@@ -149,7 +149,7 @@ function buildMigrationAuditRecord(args) {
149
149
  sourcePathsRewritten: args.sourcePathsRewritten,
150
150
  sourcePathsRemoved: args.sourcePathsRemoved,
151
151
  toVersion: LATEST_KB_SCHEMA_VERSION,
152
- warning: args.warning,
152
+ preMigrationWarning: args.preMigrationWarning,
153
153
  steps: args.steps,
154
154
  };
155
155
  }
@@ -534,7 +534,7 @@ export async function migrateCommand(options = {}) {
534
534
  });
535
535
  if (supersedesUnexplained.length > 0)
536
536
  console.log(`Acknowledged ${supersedesUnexplained.length} supersede(s) recorded without a 'Why this changed' section; new supersedes must explain themselves.`);
537
- writeJsonAtomically(auditPath, buildMigrationAuditRecord({
537
+ const auditRecord = buildMigrationAuditRecord({
538
538
  branch,
539
539
  manifestPath: KB_MANIFEST_RELATIVE,
540
540
  fromVersion: configStatus.currentVersion,
@@ -545,9 +545,10 @@ export async function migrateCommand(options = {}) {
545
545
  supersededRequirementsClosed: lifecycle.closed,
546
546
  sourcePathsRewritten: lifecycle.rewritten,
547
547
  sourcePathsRemoved: lifecycle.removed,
548
- warning: migrationWarning,
548
+ preMigrationWarning: migrationWarning,
549
549
  steps: migrationSteps.map((step) => step.id),
550
- }));
550
+ });
551
+ writeJsonAtomically(auditPath, auditRecord);
551
552
  console.log(`Migrated the KB to schemaVersion ${LATEST_KB_SCHEMA_VERSION} on the canonical .kb/ layout (was ${fromVersionLabel}).`);
552
553
  if (semanticAdvisorBackfill === "pending") {
553
554
  console.log(`Marked semantic advisor backfill as pending in ${KB_MANIFEST_RELATIVE}.`);
@@ -560,8 +561,25 @@ export async function migrateCommand(options = {}) {
560
561
  }
561
562
  console.log(`Wrote migration audit metadata to ${toRelativePath(cwd, auditPath)}.`);
562
563
  console.log("Migration complete. Future 'kibi migrate' runs will be a no-op.");
563
- updateGitIgnore(cwd);
564
- return { exitCode: 0 };
564
+ const gitignoreUpdated = updateGitIgnore(cwd);
565
+ return {
566
+ exitCode: 0,
567
+ summary: {
568
+ auditPath: toRelativePath(cwd, auditPath),
569
+ audit: auditRecord,
570
+ gitignoreUpdated,
571
+ },
572
+ };
573
+ }
574
+ /**
575
+ * One line naming what an applied migration run changed, read from the audit
576
+ * record it wrote: a count of zero shows a pass that had nothing left to do
577
+ * (for example legacy links an earlier plan action already marked).
578
+ */
579
+ // implements REQ-agent-guided-migration-orchestration, REQ-cli-schema-migration
580
+ export function describeMigrationRun(summary) {
581
+ const { audit } = summary;
582
+ return `Migrated schema ${audit.fromVersion ?? "none"} -> ${audit.toVersion} (audit ${summary.auditPath}): legacy-link marks ${audit.symbolGranularityLegacyLinks}, origin backfill ${audit.entityOriginBackfill}, superseded requirements closed ${audit.supersededRequirementsClosed}, source paths rewritten ${audit.sourcePathsRewritten}, source paths removed ${audit.sourcePathsRemoved}; .gitignore ${summary.gitignoreUpdated ? "updated" : "unchanged"}.`;
565
583
  }
566
584
  const KB_MANIFEST_RELATIVE = ".kb/manifest.json";
567
585
  // implements REQ-agent-guided-migration-orchestration, REQ-cli-schema-migration
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/validation.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,0BAA0B,EAC3B,MAAM,oCAAoC,CAAC;AAU5C,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAqI/D,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,IAAI,GACR,eAAe,CA6DjB;AAED,OAAO,EAAE,0BAA0B,EAAE,CAAC"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/operations/mutation/validation.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,0BAA0B,EAC3B,MAAM,oCAAoC,CAAC;AAU5C,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AA8L/D,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,IAAI,GACR,eAAe,CA6DjB;AAED,OAAO,EAAE,0BAA0B,EAAE,CAAC"}
@@ -64,9 +64,51 @@ function unknownEntityProperties(entity) {
64
64
  const known = upsertEntitySchema.properties;
65
65
  return Object.keys(entity).filter((key) => !Object.hasOwn(known, key));
66
66
  }
67
+ /**
68
+ * The fields a type-conditional `else: { not: ... }` branch of the entity
69
+ * schema forbids, and the types that may carry them; null for any other
70
+ * schema path.
71
+ */
72
+ function typeRestrictedFields(schemaPath) {
73
+ const match = /^#\/allOf\/(\d+)\/else\/not$/.exec(schemaPath);
74
+ if (match === null)
75
+ return null;
76
+ const allOf = upsertEntitySchema.allOf;
77
+ const branch = Array.isArray(allOf) ? allOf[Number(match[1])] : undefined;
78
+ if (branch === null || typeof branch !== "object")
79
+ return null;
80
+ const record = branch;
81
+ const typeRule = record.if?.properties?.type;
82
+ const types = Array.isArray(typeRule?.enum)
83
+ ? typeRule.enum.map(String)
84
+ : typeof typeRule?.const === "string"
85
+ ? [typeRule.const]
86
+ : [];
87
+ const not = record.else?.not;
88
+ const requiredLists = [
89
+ not?.required,
90
+ ...(Array.isArray(not?.anyOf)
91
+ ? not.anyOf.map((entry) => entry?.required)
92
+ : []),
93
+ ];
94
+ const fields = requiredLists.flatMap((list) => Array.isArray(list) ? list.map(String) : []);
95
+ return types.length > 0 && fields.length > 0 ? { fields, types } : null;
96
+ }
67
97
  // implements REQ-upsert-unknown-field-guidance
68
98
  function formatEntityErrors(entity, errors) {
69
- const messages = errors.map((error) => {
99
+ // A field only some entity types carry fails a type-conditional `not`
100
+ // branch; AJV then reports "must NOT be valid" plus the "else" it chose.
101
+ const restricted = new Set(errors.flatMap((error) => error.keyword === "not" && typeRestrictedFields(error.schemaPath)
102
+ ? [error.schemaPath.replace(/\/else\/not$/, "/if")]
103
+ : []));
104
+ const visible = errors.filter((error) => !(error.keyword === "if" && restricted.has(error.schemaPath)));
105
+ const messages = visible.map((error) => {
106
+ const restriction = error.keyword === "not" ? typeRestrictedFields(error.schemaPath) : null;
107
+ if (restriction !== null) {
108
+ const present = restriction.fields.filter((field) => Object.hasOwn(entity, field));
109
+ const named = present.length > 0 ? present : restriction.fields;
110
+ return `${named.join(", ")} ${named.length === 1 ? "is" : "are"} only valid on ${restriction.types.join(" and ")} entities; remove ${named.length === 1 ? "it" : "them"} from this ${String(entity.type ?? "entity")}`;
111
+ }
70
112
  const params = error.params;
71
113
  const path = error.instancePath || "root";
72
114
  if (error.keyword === "additionalProperties" && params.additionalProperty) {
@@ -1 +1 @@
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;AAiE/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;AAi1BD;;;;;;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;AACzB;;;GAGG;AACH,WAAW,GAAE,MAAM,IAAsB,GACxC,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,CAmDD"}
1
+ {"version":3,"file":"apply-plan.d.ts","sourceRoot":"","sources":["../../../src/operations/planning/apply-plan.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAEV,gBAAgB,EAGjB,MAAM,0CAA0C,CAAC;AASlD,OAAO,EACL,KAAK,eAAe,EAIrB,MAAM,uBAAuB,CAAC;AAiE/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;AAi1BD;;;;;;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;AACzB;;;GAGG;AACH,WAAW,GAAE,MAAM,IAAsB,GACxC,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,CAmDD"}
@@ -2,7 +2,7 @@ import { createHash, randomUUID } from "node:crypto";
2
2
  import path from "node:path";
3
3
  import { OperationError } from "../../cli-errors.js";
4
4
  import { branchEnsureCommand, branchMigrateCommand, branchRecoverCommand, } from "../../commands/branch.js";
5
- import { migrateCommand } from "../../commands/migrate.js";
5
+ import { describeMigrationRun, migrateCommand, } from "../../commands/migrate.js";
6
6
  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";
@@ -2155,12 +2155,12 @@ async function applyMigrationPlan(args, context, onCommitted = () => undefined)
2155
2155
  continue;
2156
2156
  }
2157
2157
  try {
2158
- await applyMigrationAction(action, context);
2158
+ const detail = await applyMigrationAction(action, context);
2159
2159
  onCommitted();
2160
2160
  results.push({
2161
2161
  actionId: action.id,
2162
2162
  outcome: "applied",
2163
- detail: `Applied ${action.code}.`,
2163
+ detail: detail ?? `Applied ${action.code}.`,
2164
2164
  });
2165
2165
  }
2166
2166
  catch (error) {
@@ -2292,6 +2292,10 @@ async function applyMigrationPlan(args, context, onCommitted = () => undefined)
2292
2292
  structuredContent: payload,
2293
2293
  };
2294
2294
  }
2295
+ /**
2296
+ * Run one approved migration action. Returns a detail line for the action
2297
+ * result when the executor reports what it changed.
2298
+ */
2295
2299
  async function applyMigrationAction(action, context) {
2296
2300
  switch (action.code) {
2297
2301
  case "legacy_branch_storage":
@@ -2342,14 +2346,19 @@ async function applyMigrationAction(action, context) {
2342
2346
  return;
2343
2347
  case "schema_version_upgrade":
2344
2348
  case "invalid_schema_version":
2345
- case "legacy_storage_migration":
2346
- if ((await migrateCommand({
2349
+ case "legacy_storage_migration": {
2350
+ // implements REQ-agent-guided-migration-orchestration
2351
+ const run = await migrateCommand({
2347
2352
  yes: true,
2348
2353
  workspaceRoot: context.workspaceRoot,
2349
2354
  initializeMissingConfig: true,
2350
- })).exitCode !== 0)
2355
+ });
2356
+ if (run.exitCode !== 0)
2351
2357
  throw new Error("Schema migration did not complete successfully.");
2352
- return;
2358
+ return run.summary !== undefined
2359
+ ? describeMigrationRun(run.summary)
2360
+ : undefined;
2361
+ }
2353
2362
  case "symbol_refresh_coordinates":
2354
2363
  case "coverage_source_coordinates": {
2355
2364
  const result = await syncCommand({
@@ -1 +1 @@
1
- {"version":3,"file":"ingestion-boundary.d.ts","sourceRoot":"","sources":["../../../src/operations/semantic-advisor/ingestion-boundary.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAG3E,OAAO,EACL,KAAK,OAAO,EAOb,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,sBAAsB,EAAuB,MAAM,YAAY,CAAC;AAgB9E,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,EAAE,CAAC,EAAE,OAAO,CAAC;CACd,CAAC,CAAC;AAuEH,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,SAAS,oBAAoB,EAAE,EAC9C,OAAO,EAAE,sBAAsB,GAC9B,+BAA+B,CA0IjC;AAED,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,SAAS,oBAAoB,EAAE,EAC9C,OAAO,EAAE,sBAAsB,GAC9B,IAAI,CAWN;AAoDD;;;;GAIG;AAEH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,SAAS,oBAAoB,EAAE,EAC9C,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GAC9D,MAAM,GAAG,IAAI,CAUf;AAGD,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,SAAS,oBAAoB,EAAE,EAC9C,MAAM,CAAC,EAAE,QAAQ,CAAC;IAChB,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CAClE,CAAC,GACD,OAAO,CAAC,IAAI,CAAC,CAwBf"}
1
+ {"version":3,"file":"ingestion-boundary.d.ts","sourceRoot":"","sources":["../../../src/operations/semantic-advisor/ingestion-boundary.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAG3E,OAAO,EACL,KAAK,OAAO,EAOb,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,sBAAsB,EAAuB,MAAM,YAAY,CAAC;AAgB9E,MAAM,WAAW,+BAA+B;IAC9C,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,EAAE,CAAC,EAAE,OAAO,CAAC;CACd,CAAC,CAAC;AAuEH,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,SAAS,oBAAoB,EAAE,EAC9C,OAAO,EAAE,sBAAsB,GAC9B,+BAA+B,CA0IjC;AAED,wBAAgB,+BAA+B,CAC7C,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,SAAS,oBAAoB,EAAE,EAC9C,OAAO,EAAE,sBAAsB,GAC9B,IAAI,CAWN;AAoFD;;;;GAIG;AAEH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,SAAS,oBAAoB,EAAE,EAC9C,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,GAC9D,MAAM,GAAG,IAAI,CAUf;AAGD,wBAAsB,+BAA+B,CACnD,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,SAAS,oBAAoB,EAAE,EAC9C,MAAM,CAAC,EAAE,QAAQ,CAAC;IAChB,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;CAClE,CAAC,GACD,OAAO,CAAC,IAAI,CAAC,CAwBf"}
@@ -192,9 +192,33 @@ function groundingClaimKeyError(modeledClaimKeys, grounded) {
192
192
  return `Proposition-complete ingestion failed: claim '${duplicate}' has more than one logical grounding relationship.`;
193
193
  if (groundedClaimKeys.length !== modeledClaimKeys.length ||
194
194
  modeledClaimKeys.some((claimKey) => !groundedClaimKeys.includes(claimKey)))
195
- return "Proposition-complete ingestion failed: modeled proposition claim_keys must match logical grounding target claim_keys exactly.";
195
+ return `Proposition-complete ingestion failed: modeled proposition claim_keys must match logical grounding target claim_keys exactly. ${claimKeyMismatchDetail(modeledClaimKeys, grounded)}`;
196
196
  return null;
197
197
  }
198
+ /**
199
+ * Why the mismatch names both sides: a claim_key is derived from the clause
200
+ * text, so a requirement whose prose was reworded (or analyzed from another
201
+ * field than the stored semantic_text) carries keys none of its grounding
202
+ * facts declare. Listing the unmatched modeled keys and the facts with the
203
+ * keys they still declare lets the agent see the drift and pick the remedy
204
+ * without diffing the KB by hand.
205
+ */
206
+ // implements REQ-kibi-proposition-complete-ingestion
207
+ function claimKeyMismatchDetail(modeledClaimKeys, grounded) {
208
+ const groundedClaimKeys = grounded.map(([, claimKey]) => claimKey);
209
+ const ungrounded = modeledClaimKeys.filter((claimKey) => !groundedClaimKeys.includes(claimKey));
210
+ const stale = grounded.filter(([, claimKey]) => !modeledClaimKeys.includes(claimKey));
211
+ const parts = [
212
+ ungrounded.length > 0
213
+ ? `Modeled claims with no grounding fact declaring their claim_key: ${ungrounded.map((claimKey) => `'${claimKey}'`).join(", ")}.`
214
+ : "",
215
+ stale.length > 0
216
+ ? `Grounding facts whose claim_key the inventory no longer models: ${stale.map(([target, claimKey]) => `${target} ('${claimKey}')`).join(", ")}.`
217
+ : "",
218
+ "A claim_key is derived from the clause text, so reworded prose (or prose analyzed from a field other than the stored semantic_text) yields new keys. Keep the stored semantic_text wording, or kb_upsert each grounding fact with the new claim_key and claim_text (same fact id) before this write; for a change of meaning, supersede the requirement instead.",
219
+ ];
220
+ return parts.filter(Boolean).join(" ");
221
+ }
198
222
  /**
199
223
  * The write-time claim_key check, run against planned writes only. Returns
200
224
  * null when it passes or when a target is outside the plan (the write-time
@@ -0,0 +1,19 @@
1
+ import type { PrologPort } from "../../public/operations/runtime-types.js";
2
+ import type { SemanticAdvisorReceipt } from "./types.js";
3
+ /**
4
+ * Why `kb_model mode: analyze` with the `id` of a stored requirement compares
5
+ * its ledger with the stored one: a claim_key is derived from the clause
6
+ * text, so analyzing reworded prose, or the title instead of the stored
7
+ * `semantic_text`, yields keys that none of the requirement's grounding
8
+ * facts declare. The write that follows such a receipt is refused by the
9
+ * proposition-complete check, long after the agent picked the wording. The
10
+ * receipt therefore warns at analysis time, naming the stored modeled
11
+ * clauses the analysis no longer states, the facts that ground them, and the
12
+ * clauses the analysis adds, so the agent can keep the stored wording or
13
+ * re-ground the facts before writing.
14
+ *
15
+ * Returns null when the requirement is not stored, carries no recorded
16
+ * ledger, or every stored modeled clause is still among the analyzed ones.
17
+ */
18
+ export declare function storedLedgerDriftWarning(prolog: Pick<PrologPort, "query">, id: string, text: string, receipt: SemanticAdvisorReceipt): Promise<string | null>;
19
+ //# sourceMappingURL=stored-ledger-drift.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stored-ledger-drift.d.ts","sourceRoot":"","sources":["../../../src/operations/semantic-advisor/stored-ledger-drift.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0CAA0C,CAAC;AAE3E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAwCzD;;;;;;;;;;;;;;GAcG;AAEH,wBAAsB,wBAAwB,CAC5C,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,EACjC,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAkDxB"}
@@ -0,0 +1,78 @@
1
+ import { escapeAtom, parseListOfLists, parsePrologValue, } from "../../prolog/codec.js";
2
+ import { loadEntities } from "../../public/operations/discovery-entities.js";
3
+ import { SEMANTIC_INVENTORY_VERSION, isRecord, stringValue } from "./shared.js";
4
+ const LOGICAL_RELATIONSHIPS = [
5
+ "requires_property",
6
+ "requires_predicate",
7
+ "requires_rule",
8
+ ];
9
+ function atom(value) {
10
+ return stringValue(parsePrologValue(value ?? "")).replace(/^['"]|['"]$/g, "");
11
+ }
12
+ function quoted(text) {
13
+ return text ? ` ("${text}")` : "";
14
+ }
15
+ async function groundingFactsOf(prolog, id) {
16
+ const result = await prolog.query(`findall([Type,To,ClaimKey], (member(Type, [${LOGICAL_RELATIONSHIPS.join(",")}]), kb_relationship(Type, '${escapeAtom(id)}', To), ((kb_entity(To, fact, _DriftProps), memberchk(claim_key=_DriftRaw, _DriftProps), normalize_term_atom(_DriftRaw, ClaimKey)) -> true ; ClaimKey = '')), Rows)`);
17
+ if (!result.success)
18
+ return [];
19
+ return parseListOfLists(result.bindings.Rows ?? "[]").map(([type, target, claimKey]) => ({
20
+ type: atom(type),
21
+ target: atom(target),
22
+ claimKey: atom(claimKey),
23
+ }));
24
+ }
25
+ /**
26
+ * Why `kb_model mode: analyze` with the `id` of a stored requirement compares
27
+ * its ledger with the stored one: a claim_key is derived from the clause
28
+ * text, so analyzing reworded prose, or the title instead of the stored
29
+ * `semantic_text`, yields keys that none of the requirement's grounding
30
+ * facts declare. The write that follows such a receipt is refused by the
31
+ * proposition-complete check, long after the agent picked the wording. The
32
+ * receipt therefore warns at analysis time, naming the stored modeled
33
+ * clauses the analysis no longer states, the facts that ground them, and the
34
+ * clauses the analysis adds, so the agent can keep the stored wording or
35
+ * re-ground the facts before writing.
36
+ *
37
+ * Returns null when the requirement is not stored, carries no recorded
38
+ * ledger, or every stored modeled clause is still among the analyzed ones.
39
+ */
40
+ // implements REQ-kibi-proposition-complete-ingestion
41
+ export async function storedLedgerDriftWarning(prolog, id, text, receipt) {
42
+ const [stored] = await loadEntities(prolog, { id, type: "req" });
43
+ if (!stored ||
44
+ stored.semantic_inventory_version !== SEMANTIC_INVENTORY_VERSION ||
45
+ !Array.isArray(stored.semantic_inventory))
46
+ return null;
47
+ const storedInventory = stored.semantic_inventory.filter(isRecord);
48
+ const storedKeys = new Set(storedInventory.map((entry) => stringValue(entry.claim_key)));
49
+ const analyzedKeys = new Set(receipt.propositions.map(({ claim_key }) => claim_key));
50
+ const drifted = storedInventory
51
+ .filter((entry) => stringValue(entry.status) === "modeled" &&
52
+ !analyzedKeys.has(stringValue(entry.claim_key)))
53
+ .map((entry) => ({
54
+ claimKey: stringValue(entry.claim_key),
55
+ claimText: stringValue(entry.claim_text),
56
+ }));
57
+ if (drifted.length === 0)
58
+ return null;
59
+ const facts = await groundingFactsOf(prolog, id);
60
+ const groundedBy = (claimKey) => {
61
+ const matches = facts.filter((fact) => fact.claimKey === claimKey);
62
+ return matches.length > 0
63
+ ? `, grounded by ${matches.map((fact) => `${fact.target} via ${fact.type}`).join(" and ")}`
64
+ : "";
65
+ };
66
+ const missing = drifted
67
+ .map(({ claimKey, claimText }) => `'${claimKey}'${quoted(claimText)}${groundedBy(claimKey)}`)
68
+ .join("; ");
69
+ const added = receipt.propositions
70
+ .filter(({ claim_key }) => !storedKeys.has(claim_key))
71
+ .map(({ claim_key, claim_text }) => `'${claim_key}'${quoted(claim_text)}`)
72
+ .join("; ");
73
+ const storedText = stringValue(stored.semantic_text);
74
+ const cause = storedText && storedText !== text
75
+ ? `The analyzed prose differs from the stored semantic_text of ${id}.`
76
+ : "The stored clause keys were derived from different prose.";
77
+ return `Claim-key drift against the stored ledger of ${id}: stored modeled clause(s) not stated by this analysis: ${missing}.${added ? ` Clause(s) this analysis adds without a stored grounding: ${added}.` : ""} ${cause} A kb_upsert of ${id} with this ledger fails the proposition-complete claim_key check unless each affected grounding fact is first re-written with the new claim_key and claim_text (same fact id). Keep the stored semantic_text wording to keep the keys, or supersede the requirement for a change of meaning.`;
78
+ }
@@ -28,7 +28,9 @@ export declare function unexplainedSupersedes(entities: readonly AuthoredEntity[
28
28
  /** The supersede edges of an entity, as the manifest acknowledges them. */
29
29
  export declare function supersedeAcknowledgements(id: string, edges: ReadonlyMap<string, Set<string>>): string[];
30
30
  /** Evaluate the firmness rules over authored requirements and ADRs. */
31
- export declare function evaluateDecisionFirmness(entities: readonly AuthoredEntity[], edges: ReadonlyMap<string, Set<string>>, rules?: ReadonlySet<string>, acknowledged?: ReadonlySet<string>): Violation[];
31
+ export declare function evaluateDecisionFirmness(entities: readonly AuthoredEntity[], edges: ReadonlyMap<string, Set<string>>, rules?: ReadonlySet<string>, acknowledged?: ReadonlySet<string>, options?: Readonly<{
32
+ schemaVersion?: number | null;
33
+ }>): Violation[];
32
34
  /** Read the authored decisions once and evaluate the selected rules. */
33
35
  export declare function collectDecisionFirmnessViolations(rules: ReadonlySet<string>, workspaceRoot: string): Violation[];
34
36
  //# sourceMappingURL=decision-firmness.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"decision-firmness.d.ts","sourceRoot":"","sources":["../../../src/public/operations/decision-firmness.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EACL,KAAK,cAAc,EAGpB,MAAM,qBAAqB,CAAC;AAE7B,wEAAwE;AAExE,eAAO,MAAM,+BAA+B,+BAA+B,CAAC;AAC5E,qEAAqE;AAErE,eAAO,MAAM,6BAA6B,6BAA6B,CAAC;AACxE,oEAAoE;AAEpE,eAAO,MAAM,8BAA8B,8BAA8B,CAAC;AAC1E,6EAA6E;AAE7E,eAAO,MAAM,mCAAmC,mCACd,CAAC;AAGnC,eAAO,MAAM,uBAAuB,oIAK1B,CAAC;AAIX,0CAA0C;AAE1C,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,cAAc,EAAE,CAS5E;AAED;;;;;GAKG;AAEH,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,SAAS,cAAc,EAAE,GAClC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CA+B1B;AASD;;;;;GAKG;AAEH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,GACtC,cAAc,EAAE,CAQlB;AAED,2EAA2E;AAE3E,wBAAgB,yBAAyB,CACvC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,GACtC,MAAM,EAAE,CAIV;AAED,uEAAuE;AAEvE,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EACvC,KAAK,GAAE,WAAW,CAAC,MAAM,CAAoC,EAC7D,YAAY,GAAE,WAAW,CAAC,MAAM,CAAa,GAC5C,SAAS,EAAE,CAiGb;AAED,wEAAwE;AAExE,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,EAC1B,aAAa,EAAE,MAAM,GACpB,SAAS,EAAE,CASb"}
1
+ {"version":3,"file":"decision-firmness.d.ts","sourceRoot":"","sources":["../../../src/public/operations/decision-firmness.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EACL,KAAK,cAAc,EAGpB,MAAM,qBAAqB,CAAC;AAE7B,wEAAwE;AAExE,eAAO,MAAM,+BAA+B,+BAA+B,CAAC;AAC5E,qEAAqE;AAErE,eAAO,MAAM,6BAA6B,6BAA6B,CAAC;AACxE,oEAAoE;AAEpE,eAAO,MAAM,8BAA8B,8BAA8B,CAAC;AAC1E,6EAA6E;AAE7E,eAAO,MAAM,mCAAmC,mCACd,CAAC;AAGnC,eAAO,MAAM,uBAAuB,oIAK1B,CAAC;AAcX,0CAA0C;AAE1C,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,cAAc,EAAE,CAS5E;AAED;;;;;GAKG;AAEH,wBAAgB,kBAAkB,CAChC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,SAAS,cAAc,EAAE,GAClC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CA+B1B;AASD;;;;;GAKG;AAEH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,GACtC,cAAc,EAAE,CAQlB;AAED,2EAA2E;AAE3E,wBAAgB,yBAAyB,CACvC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,GACtC,MAAM,EAAE,CAIV;AAED,uEAAuE;AAEvE,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EACvC,KAAK,GAAE,WAAW,CAAC,MAAM,CAAoC,EAC7D,YAAY,GAAE,WAAW,CAAC,MAAM,CAAa,EAC7C,OAAO,GAAE,QAAQ,CAAC;IAAE,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAM,GACxD,SAAS,EAAE,CAoGb;AAED,wEAAwE;AAExE,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,EAC1B,aAAa,EAAE,MAAM,GACpB,SAAS,EAAE,CAWb"}
@@ -41,6 +41,13 @@ export const DECISION_FIRMNESS_RULES = [
41
41
  SUPERSEDES_REASON_ACKNOWLEDGED_RULE,
42
42
  ];
43
43
  const DECISION_LANES = ["requirements", "adr"];
44
+ /** The schema version from which a supersede must explain itself. */
45
+ const SUPERSEDES_REASON_SCHEMA_VERSION = 9;
46
+ /**
47
+ * Told on a KB older than schema 9: the pending schema upgrade acknowledges
48
+ * supersedes recorded before the rule existed, so no edit is required now.
49
+ */
50
+ const PRE_SCHEMA9_SUPERSEDES_NOTE = " Supersedes recorded before schema 9 are acknowledged by the plan's schema-config-upgrade (kibi migrate --yes); add the reason only when you next touch the requirement.";
44
51
  /** Every authored requirement and ADR. */
45
52
  // implements REQ-kb-decision-firmness
46
53
  export function listDecisionEntities(workspaceRoot) {
@@ -123,7 +130,9 @@ export function supersedeAcknowledgements(id, edges) {
123
130
  }
124
131
  /** Evaluate the firmness rules over authored requirements and ADRs. */
125
132
  // implements REQ-kb-decision-firmness
126
- export function evaluateDecisionFirmness(entities, edges, rules = new Set(DECISION_FIRMNESS_RULES), acknowledged = new Set()) {
133
+ export function evaluateDecisionFirmness(entities, edges, rules = new Set(DECISION_FIRMNESS_RULES), acknowledged = new Set(), options = {}) {
134
+ const preSchema9 = typeof options.schemaVersion === "number" &&
135
+ options.schemaVersion < SUPERSEDES_REASON_SCHEMA_VERSION;
127
136
  const findings = [];
128
137
  const superseded = supersededIds(edges);
129
138
  const byId = new Map(entities.map((entity) => [entity.id, entity]));
@@ -186,7 +195,7 @@ export function evaluateDecisionFirmness(entities, edges, rules = new Set(DECISI
186
195
  rule: SUPERSEDES_REASON_MISSING_RULE,
187
196
  entityId: entity.id,
188
197
  description: `${entity.id} supersedes ${unacknowledged.join(", ")} without a '## ${WHY_THIS_CHANGED_HEADING}' section of at least ${MIN_WHY_CHANGED_WORDS} words`,
189
- suggestion: `Add '## ${WHY_THIS_CHANGED_HEADING}' to the body: name the evidence (a failing test, a measured cost, a constraint the old decision missed, a new requirement) and answer the superseded decision's reasoning. A preference is not evidence; propose it instead of superseding.`,
198
+ suggestion: `Add '## ${WHY_THIS_CHANGED_HEADING}' to the body: name the evidence (a failing test, a measured cost, a constraint the old decision missed, a new requirement) and answer the superseded decision's reasoning. A preference is not evidence; propose it instead of superseding.${preSchema9 ? PRE_SCHEMA9_SUPERSEDES_NOTE : ""}`,
190
199
  source: entity.path,
191
200
  evidence: { type: entity.type, supersedes: unacknowledged },
192
201
  });
@@ -212,5 +221,6 @@ export function collectDecisionFirmnessViolations(rules, workspaceRoot) {
212
221
  if (!DECISION_FIRMNESS_RULES.some((rule) => rules.has(rule)))
213
222
  return [];
214
223
  const entities = listDecisionEntities(workspaceRoot);
215
- return evaluateDecisionFirmness(entities, authoredSupersedes(workspaceRoot, entities), rules, new Set(readKbManifest(workspaceRoot)?.supersedesReasonAcknowledged ?? []));
224
+ const manifest = readKbManifest(workspaceRoot);
225
+ return evaluateDecisionFirmness(entities, authoredSupersedes(workspaceRoot, entities), rules, new Set(manifest?.supersedesReasonAcknowledged ?? []), { schemaVersion: manifest?.schemaVersion ?? null });
216
226
  }
@@ -1 +1 @@
1
- {"version":3,"file":"discovery-executors.d.ts","sourceRoot":"","sources":["../../../src/public/operations/discovery-executors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"discovery-executors.d.ts","sourceRoot":"","sources":["../../../src/public/operations/discovery-executors.ts"],"names":[],"mappings":"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"}
@@ -774,6 +774,13 @@ export async function executeStatus(_input, context) {
774
774
  : { proofSnapshotError: snapshotEvidence.error }),
775
775
  };
776
776
  const schemaStatus = readMigrationConfigStatus(context.workspaceRoot);
777
+ // implements REQ-agent-guided-migration-orchestration
778
+ // A schema upgrade plans the source rewrites kibi migrate performs with
779
+ // it; the planner loads only when an upgrade is due.
780
+ const sourcePlanner = schemaStatus.needsMigration
781
+ ? (await import("../../operations/migration/schema6.js"))
782
+ .buildSchema6MigrationFragment
783
+ : undefined;
777
784
  const migrationPlan = buildActionsFromStatus({
778
785
  workspaceRoot: context.workspaceRoot,
779
786
  branchAttachment: attachment,
@@ -788,6 +795,14 @@ export async function executeStatus(_input, context) {
788
795
  ? snapshotEvidence.snapshot.hash
789
796
  : null,
790
797
  configStatus: schemaStatus,
798
+ ...(sourcePlanner !== undefined
799
+ ? {
800
+ planSchemaUpgradeSources: (currentSchemaVersion) => sourcePlanner({
801
+ workspaceRoot: context.workspaceRoot,
802
+ currentSchemaVersion,
803
+ }),
804
+ }
805
+ : {}),
791
806
  });
792
807
  const listed = context.fs?.glob
793
808
  ? await context.fs.glob([
@@ -87,6 +87,13 @@ export declare function buildActionsFromCoverage(input: {
87
87
  repairPlan?: Readonly<Record<string, unknown>>;
88
88
  symbolRepairPlan?: Readonly<Record<string, unknown>>;
89
89
  }): MigrationAction[];
90
+ /** Source-rewrite actions a schema upgrade performs, as its planner returns them. */
91
+ export type SchemaUpgradeSourceActions = Readonly<{
92
+ actions: readonly MigrationAction[];
93
+ /** Automatic actions that rewrite authored sources; the upgrade waits on them. */
94
+ sourceRewriteActionIds: readonly string[];
95
+ diagnostics: readonly string[];
96
+ }>;
90
97
  export type MigrationConfigStatus = Readonly<{
91
98
  status: "missing" | "invalid" | "older" | "current" | "newer";
92
99
  currentVersion: number | null;
@@ -108,6 +115,12 @@ export declare function buildActionsFromStatus(input: {
108
115
  kbSnapshotId?: string | null;
109
116
  workspaceSnapshot?: string | null;
110
117
  configStatus?: MigrationConfigStatus;
118
+ /**
119
+ * Plans the authored-source rewrites `kibi migrate --yes` performs on its
120
+ * way to the latest schema (the planner `kibi migrate` itself uses), so
121
+ * the schema upgrade declares every file it touches. Read-only.
122
+ */
123
+ planSchemaUpgradeSources?: (currentSchemaVersion: number | null) => SchemaUpgradeSourceActions;
111
124
  }): MigrationPlan;
112
125
  export {};
113
126
  //# sourceMappingURL=migration-plan.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"migration-plan.d.ts","sourceRoot":"","sources":["../../../src/public/operations/migration-plan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"migration-plan.d.ts","sourceRoot":"","sources":["../../../src/public/operations/migration-plan.ts"],"names":[],"mappings":"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"}
@@ -521,6 +521,7 @@ const RESYNC_REASON_CODES = new Set([
521
521
  ]);
522
522
  export function buildActionsFromStatus(input) {
523
523
  const actions = [];
524
+ const diagnostics = [];
524
525
  const attachment = input.branchAttachment;
525
526
  const store = input.branchStore;
526
527
  const configStatus = input.configStatus ?? readMigrationConfigStatus(input.workspaceRoot);
@@ -611,6 +612,20 @@ export function buildActionsFromStatus(input) {
611
612
  }
612
613
  if (configStatus.needsMigration || legacyStorageMigrationRequired) {
613
614
  const operatorOnly = configStatus.status === "newer" || legacyStorageBlocked;
615
+ // implements REQ-agent-guided-migration-orchestration, REQ-cli-schema-migration
616
+ // The source rewrites the migrate run performs (legacy-link marks, origin
617
+ // backfill, lifecycle repairs, ...) are planned as their own actions with
618
+ // their own files, and the upgrade waits on them, so approving it means
619
+ // approving them. Knowledge still outside .kb/ is planned after it moves.
620
+ const sources = !operatorOnly &&
621
+ !legacyStorageMigrationRequired &&
622
+ input.planSchemaUpgradeSources !== undefined
623
+ ? input.planSchemaUpgradeSources(configStatus.currentVersion)
624
+ : null;
625
+ if (sources !== null) {
626
+ actions.push(...sources.actions);
627
+ diagnostics.push(...sources.diagnostics);
628
+ }
614
629
  actions.push(migrationAction({
615
630
  id: "schema-config-upgrade",
616
631
  code: configStatus.status === "invalid"
@@ -631,11 +646,20 @@ export function buildActionsFromStatus(input) {
631
646
  ".kb/manifest.json",
632
647
  ".kb/migrations",
633
648
  ".kb/config.json",
649
+ // The migrate run keeps the canonical derived entries ignored.
650
+ ".gitignore",
651
+ // Unplanned source rewrites can touch any authored .kb/ file.
652
+ ...(sources === null ? [".kb/"] : []),
634
653
  ...legacyStorage.moves.map((move) => move.from),
635
654
  ...legacyStorage.removals.map((removal) => removal.path),
636
655
  ],
637
656
  evidence: {
638
657
  configStatus,
658
+ ...(sources === null
659
+ ? {
660
+ sourceRewrites: "Not planned as separate actions: kibi migrate --yes also marks coarse symbol links legacy-link, backfills origin and repairs lifecycle findings in authored .kb/ sources. The plan lists them as their own actions once the upgrade can run automatically on the canonical .kb/ layout.",
661
+ }
662
+ : {}),
639
663
  ...(legacyStorageMigrationRequired
640
664
  ? {
641
665
  legacyStorage: {
@@ -648,7 +672,10 @@ export function buildActionsFromStatus(input) {
648
672
  }
649
673
  : {}),
650
674
  },
651
- dependsOn: storeState === "missing" ? ["branch-store-ensure"] : [],
675
+ dependsOn: [
676
+ ...(storeState === "missing" ? ["branch-store-ensure"] : []),
677
+ ...(sources?.sourceRewriteActionIds ?? []),
678
+ ],
652
679
  autoApplicable: !operatorOnly,
653
680
  }));
654
681
  }
@@ -784,5 +811,6 @@ export function buildActionsFromStatus(input) {
784
811
  ],
785
812
  incompleteDomains,
786
813
  actions,
814
+ diagnostics,
787
815
  });
788
816
  }
@@ -1 +1 @@
1
- {"version":3,"file":"semantic.d.ts","sourceRoot":"","sources":["../../../../src/public/operations/specs/semantic.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,mBAAmB,EACnB,8BAA8B,EAC/B,MAAM,+CAA+C,CAAC;AAEvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAmB5D,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,mBAAmB,EACzB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,8BAA8B,CAAC,CA2FzC;AAED,iBAAe,2BAA2B,CACxC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACxC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,8BAA8B,CAAC,CAiCzC;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2EE,CAAC"}
1
+ {"version":3,"file":"semantic.d.ts","sourceRoot":"","sources":["../../../../src/public/operations/specs/semantic.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,mBAAmB,EACnB,8BAA8B,EAE/B,MAAM,+CAA+C,CAAC;AAEvD,OAAO,KAAK,EAAE,gBAAgB,EAAc,MAAM,qBAAqB,CAAC;AA8CxE,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,mBAAmB,EACzB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,8BAA8B,CAAC,CAiGzC;AAED,iBAAe,2BAA2B,CACxC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EACxC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,8BAA8B,CAAC,CAiCzC;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2EE,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { InputError } from "../../../cli-errors.js";
2
2
  import { analyzeSemanticAdvisorInputWithPlugins } from "../../../operations/semantic-advisor/plugin-orchestration.js";
3
+ import { storedLedgerDriftWarning } from "../../../operations/semantic-advisor/stored-ledger-drift.js";
3
4
  import { publicCapabilityStamp } from "../../../plugins/compose-semantic-classifier.js";
4
5
  function requiredText(value) {
5
6
  const text = typeof value === "string" ? value.trim() : "";
@@ -12,6 +13,29 @@ function optionalString(value) {
12
13
  const text = typeof value === "string" ? value.trim() : "";
13
14
  return text || undefined;
14
15
  }
16
+ /**
17
+ * The stored-ledger comparison runs only for a requirement the caller named
18
+ * and only when the host can open the branch engine; analysis without a KB
19
+ * (a preview, a unit test, a workspace before `kibi sync`) stays as it was.
20
+ * A store that cannot be read is not an analysis failure, so the warning is
21
+ * simply absent then.
22
+ */
23
+ // implements REQ-kibi-proposition-complete-ingestion
24
+ async function storedLedgerWarnings(args, text, receipt, context) {
25
+ const id = optionalString(args.id);
26
+ if (!id || (optionalString(args.type) ?? "req") !== "req")
27
+ return [];
28
+ try {
29
+ const prolog = context?.prolog ?? (await context?.ensureProlog?.());
30
+ if (!prolog)
31
+ return [];
32
+ const warning = await storedLedgerDriftWarning(prolog, id, text, receipt);
33
+ return warning ? [warning] : [];
34
+ }
35
+ catch {
36
+ return [];
37
+ }
38
+ }
15
39
  export async function executeSemanticAdvisor(args, context) {
16
40
  const text = requiredText(args.text);
17
41
  const id = optionalString(args.id) ?? "REQ-SEMANTIC-ADVISOR-PREVIEW";
@@ -39,6 +63,7 @@ export async function executeSemanticAdvisor(args, context) {
39
63
  : {}),
40
64
  });
41
65
  const result = orchestrated.analysis;
66
+ const ledgerWarnings = await storedLedgerWarnings(args, text, result.receipt, context);
42
67
  const pluginWarnings = orchestrated.stamps.length > 0
43
68
  ? [
44
69
  `Capability plugins consulted: ${orchestrated.stamps
@@ -87,7 +112,7 @@ export async function executeSemanticAdvisor(args, context) {
87
112
  ],
88
113
  structuredContent: {
89
114
  receipt: result.receipt,
90
- warnings: [...result.warnings, ...pluginWarnings],
115
+ warnings: [...result.warnings, ...ledgerWarnings, ...pluginWarnings],
91
116
  ...(capabilityPlugins ? { capabilityPlugins } : {}),
92
117
  },
93
118
  };
@@ -2,7 +2,7 @@
2
2
  id: kibi-usage
3
3
  name: Kibi Usage
4
4
  description: Use Kibi's source-first, exact-Git, migration-aware, proof-aware operations safely across MCP or the trusted local CLI, including partial completion repair.
5
- version: 2.16.0
5
+ version: 2.16.1
6
6
  kibiCompatibility: ">=1.0.0"
7
7
  tags:
8
8
  - kibi
@@ -286,8 +286,13 @@ authored. Each one is the order the write path accepts.
286
286
  existing entity, whose stored ledger Kibi keeps.
287
287
  2. **Changing the text of a grounded requirement.** New prose means new
288
288
  claim keys, so a bare rewrite is refused with `modeled proposition
289
- claim_keys must match logical grounding target claim_keys exactly`.
290
- Prefer supersession for a change of meaning: analyze the new prose,
289
+ claim_keys must match logical grounding target claim_keys exactly`; the
290
+ error names the modeled keys no fact declares and the facts whose keys
291
+ the ledger dropped. Analyze the new prose with the requirement's `id`
292
+ first: the receipt warns `Claim-key drift against the stored ledger`
293
+ and names the grounded clauses the new wording drops (the title worded
294
+ differently from the stored `semantic_text` is the usual cause), before
295
+ any write. Prefer supersession for a change of meaning: analyze the new prose,
291
296
  write its facts, write the new requirement (`-v2`) with `supersedes` to
292
297
  the old one, then set the old one to `status: closed`. Its scenario
293
298
  follows the same rule as in recipe 1: create the new scenario (with
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kibi-cli",
3
- "version": "2.22.0",
3
+ "version": "2.22.1",
4
4
  "type": "module",
5
5
  "description": "Kibi CLI for knowledge base management",
6
6
  "engines": {
@@ -63,6 +63,16 @@ export const DECISION_FIRMNESS_RULES = [
63
63
 
64
64
  const DECISION_LANES = ["requirements", "adr"] as const;
65
65
 
66
+ /** The schema version from which a supersede must explain itself. */
67
+ const SUPERSEDES_REASON_SCHEMA_VERSION = 9;
68
+
69
+ /**
70
+ * Told on a KB older than schema 9: the pending schema upgrade acknowledges
71
+ * supersedes recorded before the rule existed, so no edit is required now.
72
+ */
73
+ const PRE_SCHEMA9_SUPERSEDES_NOTE =
74
+ " Supersedes recorded before schema 9 are acknowledged by the plan's schema-config-upgrade (kibi migrate --yes); add the reason only when you next touch the requirement.";
75
+
66
76
  /** Every authored requirement and ADR. */
67
77
  // implements REQ-kb-decision-firmness
68
78
  export function listDecisionEntities(workspaceRoot: string): AuthoredEntity[] {
@@ -164,7 +174,11 @@ export function evaluateDecisionFirmness(
164
174
  edges: ReadonlyMap<string, Set<string>>,
165
175
  rules: ReadonlySet<string> = new Set(DECISION_FIRMNESS_RULES),
166
176
  acknowledged: ReadonlySet<string> = new Set(),
177
+ options: Readonly<{ schemaVersion?: number | null }> = {},
167
178
  ): Violation[] {
179
+ const preSchema9 =
180
+ typeof options.schemaVersion === "number" &&
181
+ options.schemaVersion < SUPERSEDES_REASON_SCHEMA_VERSION;
168
182
  const findings: Violation[] = [];
169
183
  const superseded = supersededIds(edges);
170
184
  const byId = new Map(entities.map((entity) => [entity.id, entity]));
@@ -241,7 +255,7 @@ export function evaluateDecisionFirmness(
241
255
  rule: SUPERSEDES_REASON_MISSING_RULE,
242
256
  entityId: entity.id,
243
257
  description: `${entity.id} supersedes ${unacknowledged.join(", ")} without a '## ${WHY_THIS_CHANGED_HEADING}' section of at least ${MIN_WHY_CHANGED_WORDS} words`,
244
- suggestion: `Add '## ${WHY_THIS_CHANGED_HEADING}' to the body: name the evidence (a failing test, a measured cost, a constraint the old decision missed, a new requirement) and answer the superseded decision's reasoning. A preference is not evidence; propose it instead of superseding.`,
258
+ suggestion: `Add '## ${WHY_THIS_CHANGED_HEADING}' to the body: name the evidence (a failing test, a measured cost, a constraint the old decision missed, a new requirement) and answer the superseded decision's reasoning. A preference is not evidence; propose it instead of superseding.${preSchema9 ? PRE_SCHEMA9_SUPERSEDES_NOTE : ""}`,
245
259
  source: entity.path,
246
260
  evidence: { type: entity.type, supersedes: unacknowledged },
247
261
  });
@@ -271,10 +285,12 @@ export function collectDecisionFirmnessViolations(
271
285
  ): Violation[] {
272
286
  if (!DECISION_FIRMNESS_RULES.some((rule) => rules.has(rule))) return [];
273
287
  const entities = listDecisionEntities(workspaceRoot);
288
+ const manifest = readKbManifest(workspaceRoot);
274
289
  return evaluateDecisionFirmness(
275
290
  entities,
276
291
  authoredSupersedes(workspaceRoot, entities),
277
292
  rules,
278
- new Set(readKbManifest(workspaceRoot)?.supersedesReasonAcknowledged ?? []),
293
+ new Set(manifest?.supersedesReasonAcknowledged ?? []),
294
+ { schemaVersion: manifest?.schemaVersion ?? null },
279
295
  );
280
296
  }
@@ -1121,6 +1121,13 @@ export async function executeStatus(
1121
1121
  : { proofSnapshotError: snapshotEvidence.error }),
1122
1122
  };
1123
1123
  const schemaStatus = readMigrationConfigStatus(context.workspaceRoot);
1124
+ // implements REQ-agent-guided-migration-orchestration
1125
+ // A schema upgrade plans the source rewrites kibi migrate performs with
1126
+ // it; the planner loads only when an upgrade is due.
1127
+ const sourcePlanner = schemaStatus.needsMigration
1128
+ ? (await import("../../operations/migration/schema6.js"))
1129
+ .buildSchema6MigrationFragment
1130
+ : undefined;
1124
1131
  const migrationPlan = buildActionsFromStatus({
1125
1132
  workspaceRoot: context.workspaceRoot,
1126
1133
  branchAttachment: attachment,
@@ -1135,6 +1142,15 @@ export async function executeStatus(
1135
1142
  ? snapshotEvidence.snapshot.hash
1136
1143
  : null,
1137
1144
  configStatus: schemaStatus,
1145
+ ...(sourcePlanner !== undefined
1146
+ ? {
1147
+ planSchemaUpgradeSources: (currentSchemaVersion: number | null) =>
1148
+ sourcePlanner({
1149
+ workspaceRoot: context.workspaceRoot,
1150
+ currentSchemaVersion,
1151
+ }),
1152
+ }
1153
+ : {}),
1138
1154
  });
1139
1155
  const listed = context.fs?.glob
1140
1156
  ? await context.fs.glob(
@@ -616,6 +616,14 @@ export function buildActionsFromCoverage(input: {
616
616
  return actions;
617
617
  }
618
618
 
619
+ /** Source-rewrite actions a schema upgrade performs, as its planner returns them. */
620
+ export type SchemaUpgradeSourceActions = Readonly<{
621
+ actions: readonly MigrationAction[];
622
+ /** Automatic actions that rewrite authored sources; the upgrade waits on them. */
623
+ sourceRewriteActionIds: readonly string[];
624
+ diagnostics: readonly string[];
625
+ }>;
626
+
619
627
  export type MigrationConfigStatus = Readonly<{
620
628
  status: "missing" | "invalid" | "older" | "current" | "newer";
621
629
  currentVersion: number | null;
@@ -706,8 +714,17 @@ export function buildActionsFromStatus(input: {
706
714
  kbSnapshotId?: string | null;
707
715
  workspaceSnapshot?: string | null;
708
716
  configStatus?: MigrationConfigStatus;
717
+ /**
718
+ * Plans the authored-source rewrites `kibi migrate --yes` performs on its
719
+ * way to the latest schema (the planner `kibi migrate` itself uses), so
720
+ * the schema upgrade declares every file it touches. Read-only.
721
+ */
722
+ planSchemaUpgradeSources?: (
723
+ currentSchemaVersion: number | null,
724
+ ) => SchemaUpgradeSourceActions;
709
725
  }): MigrationPlan {
710
726
  const actions: MigrationAction[] = [];
727
+ const diagnostics: string[] = [];
711
728
  const attachment = input.branchAttachment;
712
729
  const store = input.branchStore;
713
730
  const configStatus =
@@ -813,6 +830,21 @@ export function buildActionsFromStatus(input: {
813
830
  if (configStatus.needsMigration || legacyStorageMigrationRequired) {
814
831
  const operatorOnly =
815
832
  configStatus.status === "newer" || legacyStorageBlocked;
833
+ // implements REQ-agent-guided-migration-orchestration, REQ-cli-schema-migration
834
+ // The source rewrites the migrate run performs (legacy-link marks, origin
835
+ // backfill, lifecycle repairs, ...) are planned as their own actions with
836
+ // their own files, and the upgrade waits on them, so approving it means
837
+ // approving them. Knowledge still outside .kb/ is planned after it moves.
838
+ const sources =
839
+ !operatorOnly &&
840
+ !legacyStorageMigrationRequired &&
841
+ input.planSchemaUpgradeSources !== undefined
842
+ ? input.planSchemaUpgradeSources(configStatus.currentVersion)
843
+ : null;
844
+ if (sources !== null) {
845
+ actions.push(...sources.actions);
846
+ diagnostics.push(...sources.diagnostics);
847
+ }
816
848
  actions.push(
817
849
  migrationAction({
818
850
  id: "schema-config-upgrade",
@@ -835,11 +867,21 @@ export function buildActionsFromStatus(input: {
835
867
  ".kb/manifest.json",
836
868
  ".kb/migrations",
837
869
  ".kb/config.json",
870
+ // The migrate run keeps the canonical derived entries ignored.
871
+ ".gitignore",
872
+ // Unplanned source rewrites can touch any authored .kb/ file.
873
+ ...(sources === null ? [".kb/"] : []),
838
874
  ...legacyStorage.moves.map((move) => move.from),
839
875
  ...legacyStorage.removals.map((removal) => removal.path),
840
876
  ],
841
877
  evidence: {
842
878
  configStatus,
879
+ ...(sources === null
880
+ ? {
881
+ sourceRewrites:
882
+ "Not planned as separate actions: kibi migrate --yes also marks coarse symbol links legacy-link, backfills origin and repairs lifecycle findings in authored .kb/ sources. The plan lists them as their own actions once the upgrade can run automatically on the canonical .kb/ layout.",
883
+ }
884
+ : {}),
843
885
  ...(legacyStorageMigrationRequired
844
886
  ? {
845
887
  legacyStorage: {
@@ -852,7 +894,10 @@ export function buildActionsFromStatus(input: {
852
894
  }
853
895
  : {}),
854
896
  },
855
- dependsOn: storeState === "missing" ? ["branch-store-ensure"] : [],
897
+ dependsOn: [
898
+ ...(storeState === "missing" ? ["branch-store-ensure"] : []),
899
+ ...(sources?.sourceRewriteActionIds ?? []),
900
+ ],
856
901
  autoApplicable: !operatorOnly,
857
902
  }),
858
903
  );
@@ -1021,5 +1066,6 @@ export function buildActionsFromStatus(input: {
1021
1066
  ],
1022
1067
  incompleteDomains,
1023
1068
  actions,
1069
+ diagnostics,
1024
1070
  });
1025
1071
  }
@@ -1,11 +1,13 @@
1
1
  import { InputError } from "../../../cli-errors.js";
2
2
  import { analyzeSemanticAdvisorInputWithPlugins } from "../../../operations/semantic-advisor/plugin-orchestration.js";
3
+ import { storedLedgerDriftWarning } from "../../../operations/semantic-advisor/stored-ledger-drift.js";
3
4
  import type {
4
5
  SemanticAdvisorArgs,
5
6
  SemanticAdvisorOperationResult,
7
+ SemanticAdvisorReceipt,
6
8
  } from "../../../operations/semantic-advisor/types.js";
7
9
  import { publicCapabilityStamp } from "../../../plugins/compose-semantic-classifier.js";
8
- import type { OperationContext } from "../runtime-types.js";
10
+ import type { OperationContext, PrologPort } from "../runtime-types.js";
9
11
  import type { OperationSpec } from "../types.js";
10
12
 
11
13
  function requiredText(value: unknown): string {
@@ -24,6 +26,33 @@ function optionalString(value: unknown): string | undefined {
24
26
  return text || undefined;
25
27
  }
26
28
 
29
+ /**
30
+ * The stored-ledger comparison runs only for a requirement the caller named
31
+ * and only when the host can open the branch engine; analysis without a KB
32
+ * (a preview, a unit test, a workspace before `kibi sync`) stays as it was.
33
+ * A store that cannot be read is not an analysis failure, so the warning is
34
+ * simply absent then.
35
+ */
36
+ // implements REQ-kibi-proposition-complete-ingestion
37
+ async function storedLedgerWarnings(
38
+ args: SemanticAdvisorArgs,
39
+ text: string,
40
+ receipt: SemanticAdvisorReceipt,
41
+ context?: OperationContext,
42
+ ): Promise<readonly string[]> {
43
+ const id = optionalString(args.id);
44
+ if (!id || (optionalString(args.type) ?? "req") !== "req") return [];
45
+ try {
46
+ const prolog: PrologPort | undefined =
47
+ context?.prolog ?? (await context?.ensureProlog?.());
48
+ if (!prolog) return [];
49
+ const warning = await storedLedgerDriftWarning(prolog, id, text, receipt);
50
+ return warning ? [warning] : [];
51
+ } catch {
52
+ return [];
53
+ }
54
+ }
55
+
27
56
  export async function executeSemanticAdvisor(
28
57
  args: SemanticAdvisorArgs,
29
58
  context?: OperationContext,
@@ -57,6 +86,12 @@ export async function executeSemanticAdvisor(
57
86
  },
58
87
  );
59
88
  const result = orchestrated.analysis;
89
+ const ledgerWarnings = await storedLedgerWarnings(
90
+ args,
91
+ text,
92
+ result.receipt,
93
+ context,
94
+ );
60
95
  const pluginWarnings =
61
96
  orchestrated.stamps.length > 0
62
97
  ? [
@@ -114,7 +149,7 @@ export async function executeSemanticAdvisor(
114
149
  ],
115
150
  structuredContent: {
116
151
  receipt: result.receipt,
117
- warnings: [...result.warnings, ...pluginWarnings],
152
+ warnings: [...result.warnings, ...ledgerWarnings, ...pluginWarnings],
118
153
  ...(capabilityPlugins ? { capabilityPlugins } : {}),
119
154
  },
120
155
  };
@@ -2,7 +2,7 @@
2
2
  id: kibi-usage
3
3
  name: Kibi Usage
4
4
  description: Use Kibi's source-first, exact-Git, migration-aware, proof-aware operations safely across MCP or the trusted local CLI, including partial completion repair.
5
- version: 2.16.0
5
+ version: 2.16.1
6
6
  kibiCompatibility: ">=1.0.0"
7
7
  tags:
8
8
  - kibi
@@ -286,8 +286,13 @@ authored. Each one is the order the write path accepts.
286
286
  existing entity, whose stored ledger Kibi keeps.
287
287
  2. **Changing the text of a grounded requirement.** New prose means new
288
288
  claim keys, so a bare rewrite is refused with `modeled proposition
289
- claim_keys must match logical grounding target claim_keys exactly`.
290
- Prefer supersession for a change of meaning: analyze the new prose,
289
+ claim_keys must match logical grounding target claim_keys exactly`; the
290
+ error names the modeled keys no fact declares and the facts whose keys
291
+ the ledger dropped. Analyze the new prose with the requirement's `id`
292
+ first: the receipt warns `Claim-key drift against the stored ledger`
293
+ and names the grounded clauses the new wording drops (the title worded
294
+ differently from the stored `semantic_text` is the usual cause), before
295
+ any write. Prefer supersession for a change of meaning: analyze the new prose,
291
296
  write its facts, write the new requirement (`-v2`) with `supersedes` to
292
297
  the old one, then set the old one to `status: closed`. Its scenario
293
298
  follows the same rule as in recipe 1: create the new scenario (with