kibi-cli 2.25.0 → 2.26.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.
- package/dist/cli-errors.d.ts +14 -0
- package/dist/cli-errors.d.ts.map +1 -1
- package/dist/cli-errors.js +31 -0
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +28 -0
- package/dist/commands/migrate.d.ts +2 -0
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +115 -4
- package/dist/commands/sync/cache.d.ts +30 -0
- package/dist/commands/sync/cache.d.ts.map +1 -1
- package/dist/commands/sync/cache.js +61 -0
- package/dist/commands/sync/extraction.d.ts +6 -0
- package/dist/commands/sync/extraction.d.ts.map +1 -1
- package/dist/commands/sync/extraction.js +4 -1
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +27 -1
- package/dist/operations/bootstrap/claim-restatement.d.ts +37 -0
- package/dist/operations/bootstrap/claim-restatement.d.ts.map +1 -0
- package/dist/operations/bootstrap/claim-restatement.js +83 -0
- package/dist/operations/bootstrap/generate.d.ts.map +1 -1
- package/dist/operations/bootstrap/generate.js +23 -12
- package/dist/operations/bootstrap/intent-claims.d.ts +5 -2
- package/dist/operations/bootstrap/intent-claims.d.ts.map +1 -1
- package/dist/operations/bootstrap/intent-claims.js +44 -4
- package/dist/operations/migration/requirement-status.d.ts +41 -2
- package/dist/operations/migration/requirement-status.d.ts.map +1 -1
- package/dist/operations/migration/requirement-status.js +75 -7
- package/dist/operations/migration/schema6.d.ts +9 -5
- package/dist/operations/migration/schema6.d.ts.map +1 -1
- package/dist/operations/migration/schema6.js +82 -13
- package/dist/operations/migration/symbol-coordinates-refresh.d.ts +36 -0
- package/dist/operations/migration/symbol-coordinates-refresh.d.ts.map +1 -0
- package/dist/operations/migration/symbol-coordinates-refresh.js +99 -0
- package/dist/operations/mutation/source-authoring.d.ts +9 -0
- package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
- package/dist/operations/mutation/source-authoring.js +20 -0
- package/dist/operations/mutation/stored-entity.d.ts +5 -0
- package/dist/operations/mutation/stored-entity.d.ts.map +1 -1
- package/dist/operations/mutation/uncompiled-source.d.ts +43 -0
- package/dist/operations/mutation/uncompiled-source.d.ts.map +1 -0
- package/dist/operations/mutation/uncompiled-source.js +115 -0
- package/dist/operations/mutation/upsert.d.ts +6 -0
- package/dist/operations/mutation/upsert.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.js +32 -5
- package/dist/public/impact/analyzer.d.ts.map +1 -1
- package/dist/public/impact/analyzer.js +13 -3
- package/dist/public/impact/diagnostics.js +1 -1
- package/dist/public/impact/unowned-files.d.ts +31 -0
- package/dist/public/impact/unowned-files.d.ts.map +1 -0
- package/dist/public/impact/unowned-files.js +171 -0
- package/dist/public/operations/catalog.d.ts +1 -1
- package/dist/public/operations/discovery-entities.d.ts +11 -0
- package/dist/public/operations/discovery-entities.d.ts.map +1 -1
- package/dist/public/operations/discovery-entities.js +28 -0
- package/dist/public/operations/discovery-executors.d.ts.map +1 -1
- package/dist/public/operations/discovery-executors.js +13 -1
- package/dist/public/operations/result-envelope.d.ts +2 -0
- package/dist/public/operations/result-envelope.d.ts.map +1 -1
- package/dist/public/operations/result-envelope.js +1 -0
- package/dist/public/operations/source-relationship-parity.d.ts.map +1 -1
- package/dist/public/operations/source-relationship-parity.js +22 -7
- package/dist/public/operations/specs/check.d.ts +1 -1
- package/dist/public/operations/specs/check.js +1 -1
- package/dist/public/skills/kibi-bootstrap/SKILL.md +2 -2
- package/dist/public/skills/kibi-usage/SKILL.md +11 -5
- package/dist/traceability/git-change-snapshot.d.ts.map +1 -1
- package/dist/traceability/git-change-snapshot.js +44 -3
- package/dist/traceability/staged-diagnostics.d.ts +1 -1
- package/dist/traceability/staged-diagnostics.d.ts.map +1 -1
- package/dist/traceability/staged-migration.d.ts +13 -0
- package/dist/traceability/staged-migration.d.ts.map +1 -0
- package/dist/traceability/staged-migration.js +59 -0
- package/dist/traceability/staged-symbols-manifest.d.ts +11 -0
- package/dist/traceability/staged-symbols-manifest.d.ts.map +1 -1
- package/dist/traceability/staged-symbols-manifest.js +50 -16
- package/package.json +2 -2
- package/src/public/impact/analyzer.ts +21 -7
- package/src/public/impact/diagnostics.ts +1 -1
- package/src/public/impact/unowned-files.ts +229 -0
- package/src/public/operations/discovery-entities.ts +36 -0
- package/src/public/operations/discovery-executors.ts +17 -1
- package/src/public/operations/result-envelope.ts +3 -0
- package/src/public/operations/source-relationship-parity.ts +22 -7
- package/src/public/operations/specs/check.ts +1 -1
- package/src/public/skills/kibi-bootstrap/SKILL.md +2 -2
- package/src/public/skills/kibi-usage/SKILL.md +11 -5
package/dist/cli-errors.d.ts
CHANGED
|
@@ -12,4 +12,18 @@ export declare class OperationError extends Error {
|
|
|
12
12
|
readonly exitCode = 1;
|
|
13
13
|
constructor(code: string, detail: string, retryable?: boolean);
|
|
14
14
|
}
|
|
15
|
+
/** The error envelope fields a thrown Kibi error carries. */
|
|
16
|
+
export type CodedErrorFields = {
|
|
17
|
+
readonly code: string;
|
|
18
|
+
readonly message: string;
|
|
19
|
+
readonly retryable: boolean;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* The code, message and retryability of a thrown InputError or
|
|
23
|
+
* OperationError, so the CLI JSON route and the MCP server answer it with the
|
|
24
|
+
* same error envelope. A copy of these classes bundled into another package
|
|
25
|
+
* fails `instanceof`, so an error with the same name and a code-shaped `code`
|
|
26
|
+
* counts too. Any other error carries no Kibi code and returns null.
|
|
27
|
+
*/
|
|
28
|
+
export declare function codedErrorOf(error: unknown): CodedErrorFields | null;
|
|
15
29
|
//# sourceMappingURL=cli-errors.d.ts.map
|
package/dist/cli-errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-errors.d.ts","sourceRoot":"","sources":["../src/cli-errors.ts"],"names":[],"mappings":"AACA,qBAAa,UAAW,SAAQ,KAAK;IAMjC,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM;IALzB,QAAQ,CAAC,QAAQ,KAAK;IACtB,QAAQ,CAAC,SAAS,SAAS;gBAGhB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM;CAK1B;AAGD,qBAAa,cAAe,SAAQ,KAAK;IAKrC,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,SAAS;IALpB,QAAQ,CAAC,QAAQ,KAAK;gBAGX,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,UAAO;CAK5B"}
|
|
1
|
+
{"version":3,"file":"cli-errors.d.ts","sourceRoot":"","sources":["../src/cli-errors.ts"],"names":[],"mappings":"AACA,qBAAa,UAAW,SAAQ,KAAK;IAMjC,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM;IALzB,QAAQ,CAAC,QAAQ,KAAK;IACtB,QAAQ,CAAC,SAAS,SAAS;gBAGhB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM;CAK1B;AAGD,qBAAa,cAAe,SAAQ,KAAK;IAKrC,QAAQ,CAAC,IAAI,EAAE,MAAM;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,SAAS;IALpB,QAAQ,CAAC,QAAQ,KAAK;gBAGX,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,UAAO;CAK5B;AAED,6DAA6D;AAE7D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B,CAAC;AAIF;;;;;;GAMG;AAEH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,gBAAgB,GAAG,IAAI,CA4BpE"}
|
package/dist/cli-errors.js
CHANGED
|
@@ -27,3 +27,34 @@ export class OperationError extends Error {
|
|
|
27
27
|
this.name = "OperationError";
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
|
+
const ERROR_CODE = /^[A-Z][A-Z0-9_]*$/;
|
|
31
|
+
/**
|
|
32
|
+
* The code, message and retryability of a thrown InputError or
|
|
33
|
+
* OperationError, so the CLI JSON route and the MCP server answer it with the
|
|
34
|
+
* same error envelope. A copy of these classes bundled into another package
|
|
35
|
+
* fails `instanceof`, so an error with the same name and a code-shaped `code`
|
|
36
|
+
* counts too. Any other error carries no Kibi code and returns null.
|
|
37
|
+
*/
|
|
38
|
+
// implements REQ-mcp-coded-error-envelope
|
|
39
|
+
export function codedErrorOf(error) {
|
|
40
|
+
if (error instanceof InputError || error instanceof OperationError)
|
|
41
|
+
return {
|
|
42
|
+
code: error.code,
|
|
43
|
+
message: error.detail,
|
|
44
|
+
retryable: error.retryable,
|
|
45
|
+
};
|
|
46
|
+
if (!(error instanceof Error))
|
|
47
|
+
return null;
|
|
48
|
+
const candidate = error;
|
|
49
|
+
if ((candidate.name !== "InputError" && candidate.name !== "OperationError") ||
|
|
50
|
+
typeof candidate.code !== "string" ||
|
|
51
|
+
!ERROR_CODE.test(candidate.code))
|
|
52
|
+
return null;
|
|
53
|
+
return {
|
|
54
|
+
code: candidate.code,
|
|
55
|
+
message: typeof candidate.detail === "string" ? candidate.detail : error.message,
|
|
56
|
+
retryable: typeof candidate.retryable === "boolean"
|
|
57
|
+
? candidate.retryable
|
|
58
|
+
: candidate.name === "OperationError",
|
|
59
|
+
};
|
|
60
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAqCA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAqCA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAkF7C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAE3D,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AA6hBD,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,CAAC,EACtC,MAAM,EAAE,CAAC,GAAG,IAAI,GAAG,SAAS,EAC5B,MAAM,EAAE,CAAC,GAAG,IAAI,GAAG,SAAS,GAC3B,WAAW,CAAC,CAAC,GAAG,CAAC,CAAC,CAMpB;AAGD,wBAAsB,YAAY,CAChC,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAgqB/B;AAED,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC,CAoDtB;AAID,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,MAAM,EAAE,CAAC,CAgBnB;AAED,wBAAsB,eAAe,CACnC,MAAM,EAAE,aAAa,EACrB,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,EAAE,CAAC,CAiBnB;AAED,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC,CAkEtB;AAID,wBAAsB,aAAa,CACjC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC,CAmGtB;AAED,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,EACrB,YAAY,EAAE,MAAM,EAAE,GACrB,OAAO,CAAC,SAAS,EAAE,CAAC,CAyCtB;AAED,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC,CAgDtB;AAED,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC,CA0BtB;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC,CAqBtB;AAED,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC,CAqBtB;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,SAAS,EAAE,CAAC,CAqBtB"}
|
package/dist/commands/check.js
CHANGED
|
@@ -39,6 +39,7 @@ import { createStagedEntityIdStyleDiagnostics } from "../traceability/staged-ent
|
|
|
39
39
|
import { analyzeStagedFileCoverage, } from "../traceability/staged-file-coverage.js";
|
|
40
40
|
import { classifyKibiImpactEvidence, isBehaviorSourceEdit, parseKibiImpactOverride, } from "../traceability/staged-impact-contract.js";
|
|
41
41
|
import { stagedInventoryDriftViolations } from "../traceability/staged-inventory-drift.js";
|
|
42
|
+
import { stagedCommitCarriesMigration } from "../traceability/staged-migration.js";
|
|
42
43
|
import { assessStagedSymbolsManifest, collectStagedAuthoredSymbolsManifestEvidence, } from "../traceability/staged-symbols-manifest.js";
|
|
43
44
|
import { createManifestLookupSentinelKey, extractSymbolsFromStagedFileAsync, } from "../traceability/symbol-extract.js";
|
|
44
45
|
import { cleanupTempKb, consultOverlay, createOverlayFacts, createTempKb, projectStagedEntities, } from "../traceability/temp-kb.js";
|
|
@@ -323,6 +324,13 @@ function noValidatedSymbolsMessage(sourceAnalysis) {
|
|
|
323
324
|
function uniqueSorted(values) {
|
|
324
325
|
return Array.from(new Set(values)).sort();
|
|
325
326
|
}
|
|
327
|
+
/** The Baseline-style line naming records changed only by a migration. */
|
|
328
|
+
// implements REQ-cli-migration-first-commit
|
|
329
|
+
function migrationOnlyNote(entityIds) {
|
|
330
|
+
const shown = entityIds.slice(0, 5).join(", ");
|
|
331
|
+
const more = entityIds.length > 5 ? ` and ${entityIds.length - 5} more` : "";
|
|
332
|
+
return `Migration commit: ${entityIds.length} symbol record(s) changed only by kibi migrate (legacy-link marks, review:context-missing tags) are not judged as changed by this commit: ${shown}${more}. Run kibi check for the full report.`;
|
|
333
|
+
}
|
|
326
334
|
function hasYamlFrontmatter(content) {
|
|
327
335
|
const trimmed = content.trimStart();
|
|
328
336
|
return trimmed.startsWith("---") && trimmed.slice(3).includes("\n---");
|
|
@@ -361,7 +369,10 @@ function buildStagedKibiImpactEvidence(options) {
|
|
|
361
369
|
...(options.readBaseFile ? { readBaseFile: options.readBaseFile } : {}),
|
|
362
370
|
stagedFiles,
|
|
363
371
|
sourceFiles: behaviorSourceFiles,
|
|
372
|
+
ignoreMigrationOwnedEdits: options.ignoreMigrationOwnedEdits === true,
|
|
364
373
|
});
|
|
374
|
+
if (stagedAuthoredSymbolsEvidence.migrationOnlyEntityIds !== undefined)
|
|
375
|
+
options.onMigrationOnlySymbols?.(stagedAuthoredSymbolsEvidence.migrationOnlyEntityIds);
|
|
365
376
|
const resolvedKbArtifacts = [];
|
|
366
377
|
let override = null;
|
|
367
378
|
for (const file of markdownFiles) {
|
|
@@ -670,7 +681,24 @@ export async function checkCommand(options) {
|
|
|
670
681
|
...scopedManifestResults,
|
|
671
682
|
...markdownResultsByPath.values(),
|
|
672
683
|
];
|
|
684
|
+
const readTreeFile = (tree) => (filePath) => {
|
|
685
|
+
try {
|
|
686
|
+
return snapshot
|
|
687
|
+
.readGit(["show", `${tree}:${filePath}`])
|
|
688
|
+
.toString("utf8");
|
|
689
|
+
}
|
|
690
|
+
catch {
|
|
691
|
+
return null;
|
|
692
|
+
}
|
|
693
|
+
};
|
|
694
|
+
// A commit that carries a kibi migrate run is not charged with the
|
|
695
|
+
// fields the migration rewrote mechanically in existing records.
|
|
696
|
+
const carriesMigration = stagedCommitCarriesMigration(readTreeFile(snapshot.baseTree), readTreeFile(snapshot.headTree));
|
|
673
697
|
const stagedKibiEvidence = buildStagedKibiImpactEvidence({
|
|
698
|
+
ignoreMigrationOwnedEdits: carriesMigration,
|
|
699
|
+
onMigrationOnlySymbols: (entityIds) => {
|
|
700
|
+
baselineNotes.push(migrationOnlyNote(entityIds));
|
|
701
|
+
},
|
|
674
702
|
analyzeSource: (filePath) => {
|
|
675
703
|
const result = sourceAnalysis.get(filePath)?.after;
|
|
676
704
|
if (!result)
|
|
@@ -31,6 +31,8 @@ export interface MigrationAuditRecord {
|
|
|
31
31
|
sourcePathsRewritten: number;
|
|
32
32
|
/** Authored source values this run removed: they named the entity's own file or nothing. */
|
|
33
33
|
sourcePathsRemoved: number;
|
|
34
|
+
/** Requirements whose delivery status (implemented, done, completed) this run mapped to closed plus tag implemented. */
|
|
35
|
+
legacyStatusesMapped: number;
|
|
34
36
|
toVersion: number;
|
|
35
37
|
/** The schema warning the KB showed before this run migrated it. */
|
|
36
38
|
preMigrationWarning: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../../src/commands/migrate.ts"],"names":[],"mappings":"AA0DA,OAAO,KAAK,EACV,eAAe,EAEhB,MAAM,wCAAwC,CAAC;AAwBhD,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,6EAA6E;IAC7E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,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,wHAAwH;IACxH,oBAAoB,EAAE,MAAM,CAAC;IAC7B,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;AAgJD,wBAAgB,mBAAmB,CACjC,gBAAgB,EAAE,OAAO,EACzB,UAAU,EAAE,MAAM,GAAG,IAAI,GACxB,MAAM,CAUR;AAiWD,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,CAkd9D;AAED;;;;GAIG;AAEH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAGzE;AA+WD;;;;;GAKG;AAEH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,CAAC,GACpC,OAAO,CAOT"}
|
package/dist/commands/migrate.js
CHANGED
|
@@ -19,8 +19,10 @@ import { existsSync, mkdirSync, renameSync, writeFileSync, } from "node:fs";
|
|
|
19
19
|
import * as path from "node:path";
|
|
20
20
|
import { applySafeInventoryRederivations, planInventoryRederivation, } from "../operations/migration/inventory-rederive.js";
|
|
21
21
|
import { applyOriginBackfill, planOriginBackfill, } from "../operations/migration/origin-backfill.js";
|
|
22
|
+
import { applyDeliveredStatusMappings, planRequirementStatusMappings, } from "../operations/migration/requirement-status.js";
|
|
22
23
|
import { applySourcePathRepairs, findSourceRepairs, } from "../operations/migration/source-paths.js";
|
|
23
24
|
import { applySupersededClosures, planSupersededClosures, } from "../operations/migration/superseded-closure.js";
|
|
25
|
+
import { coordinateRefreshFailureMessage, readGeneratedManifestBytes, refreshCoordinatesAfterMigration, } from "../operations/migration/symbol-coordinates-refresh.js";
|
|
24
26
|
import { applySymbolLegacyLinks, planSymbolLegacyLinks, } from "../operations/migration/symbol-legacy-links.js";
|
|
25
27
|
import { resolveBranchAttachment } from "../utils/branch-resolver.js";
|
|
26
28
|
import { defaultKbManifest, readKbManifest, readKbManifestStatus, writeKbManifest, } from "../utils/kb-manifest.js";
|
|
@@ -155,6 +157,7 @@ function buildMigrationAuditRecord(args) {
|
|
|
155
157
|
supersededRequirementsClosed: args.supersededRequirementsClosed,
|
|
156
158
|
sourcePathsRewritten: args.sourcePathsRewritten,
|
|
157
159
|
sourcePathsRemoved: args.sourcePathsRemoved,
|
|
160
|
+
legacyStatusesMapped: args.legacyStatusesMapped,
|
|
158
161
|
toVersion: LATEST_KB_SCHEMA_VERSION,
|
|
159
162
|
preMigrationWarning: args.preMigrationWarning,
|
|
160
163
|
steps: args.steps,
|
|
@@ -187,6 +190,19 @@ function markLegacySymbolLinks(cwd, dryRun, manifestPath) {
|
|
|
187
190
|
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.`);
|
|
188
191
|
return marked.length;
|
|
189
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* Refresh generated symbol coordinates after the migration rewrote or moved
|
|
195
|
+
* .kb/symbols.yaml, so the first commit does not hit the generated-manifest
|
|
196
|
+
* gate. A failure leaves the migration applied and names the manual step.
|
|
197
|
+
*/
|
|
198
|
+
// implements REQ-cli-migration-first-commit
|
|
199
|
+
async function refreshMigratedSymbolCoordinates(cwd, before) {
|
|
200
|
+
const refresh = await refreshCoordinatesAfterMigration(cwd, before);
|
|
201
|
+
if (refresh.outcome === "refreshed")
|
|
202
|
+
console.log("Refreshed generated symbol coordinates for the migrated .kb/symbols.yaml; stage .kb/symbols.yaml and .kb/symbol-coordinates.yaml with the migration.");
|
|
203
|
+
else if (refresh.outcome === "failed")
|
|
204
|
+
printWarning(coordinateRefreshFailureMessage(refresh.reason));
|
|
205
|
+
}
|
|
190
206
|
function describeRederivation(plan) {
|
|
191
207
|
const { keptModeled, roleChanges, newlyUnresolved, downgradedModeled } = plan.summary;
|
|
192
208
|
return `${plan.requirementId}: ${keptModeled} modeled claim(s) kept, ${roleChanges} role change(s), ${newlyUnresolved} claim(s) now unresolved, ${downgradedModeled} modeled claim(s) downgraded`;
|
|
@@ -300,6 +316,74 @@ function repairLifecycleFindings(cwd, dryRun) {
|
|
|
300
316
|
manual: supersession.cycles.length + unrepaired.length,
|
|
301
317
|
};
|
|
302
318
|
}
|
|
319
|
+
function describeDeliveredMappings(findings) {
|
|
320
|
+
const byStatus = new Map();
|
|
321
|
+
for (const finding of findings) {
|
|
322
|
+
byStatus.set(finding.status, [
|
|
323
|
+
...(byStatus.get(finding.status) ?? []),
|
|
324
|
+
finding,
|
|
325
|
+
]);
|
|
326
|
+
}
|
|
327
|
+
return [...byStatus]
|
|
328
|
+
.map(([status, group]) => `legacy status ${status} -> ${group[0]?.automatic?.status ?? "closed"} (tag ${group[0]?.automatic?.tag ?? "implemented"}) on ${group.length} requirement(s): ${group.map((finding) => finding.requirementId).join(", ")}`)
|
|
329
|
+
.join("; ");
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Map delivery statuses (implemented, done, completed) to closed plus the tag
|
|
333
|
+
* implemented: kibi sync cannot compile them, and that is their one lossless
|
|
334
|
+
* reading. Returns the requirement statuses a person still has to decide.
|
|
335
|
+
*/
|
|
336
|
+
// implements REQ-cli-schema-migration
|
|
337
|
+
function mapLegacyRequirementStatuses(cwd, dryRun) {
|
|
338
|
+
const findings = planRequirementStatusMappings(cwd);
|
|
339
|
+
const delivered = findings.filter((finding) => finding.automatic !== null);
|
|
340
|
+
if (dryRun) {
|
|
341
|
+
const review = findings.filter((finding) => finding.automatic === null);
|
|
342
|
+
if (delivered.length > 0)
|
|
343
|
+
console.log(`dry run: would map ${describeDeliveredMappings(delivered)}.`);
|
|
344
|
+
if (review.length > 0)
|
|
345
|
+
console.log(`dry run: ${review.length} requirement status(es) need a person to choose the current status: ${review.map((finding) => `${finding.requirementId} (${finding.status})`).join(", ")}; kibi migrate --format json lists them as req_status_vocabulary_map.`);
|
|
346
|
+
return { mapped: delivered.length, review };
|
|
347
|
+
}
|
|
348
|
+
if (delivered.length === 0)
|
|
349
|
+
return { mapped: 0, review: findings };
|
|
350
|
+
const result = applyDeliveredStatusMappings(cwd);
|
|
351
|
+
if (result.mapped.length > 0)
|
|
352
|
+
console.log(`Mapped ${describeDeliveredMappings(result.mapped)}.`);
|
|
353
|
+
for (const skip of result.skipped)
|
|
354
|
+
printWarning(`Status not mapped for ${skip.path}: ${skip.reason}.`);
|
|
355
|
+
return {
|
|
356
|
+
mapped: result.mapped.length,
|
|
357
|
+
review: planRequirementStatusMappings(cwd),
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Print what a `kibi migrate --yes` run left for a person, naming the
|
|
362
|
+
* requirements kibi sync cannot compile first. Returns false when nothing
|
|
363
|
+
* remains, so the caller may call the migration complete.
|
|
364
|
+
*/
|
|
365
|
+
// implements REQ-cli-schema-migration
|
|
366
|
+
function printRemainingMigrationWork(remaining) {
|
|
367
|
+
const { statuses, manualInventories, manualLifecycle } = remaining;
|
|
368
|
+
if (statuses.length === 0 && manualInventories === 0 && manualLifecycle === 0)
|
|
369
|
+
return false;
|
|
370
|
+
const uncompiled = statuses.filter((finding) => finding.extractionError !== null);
|
|
371
|
+
const skipped = statuses.filter((finding) => finding.extractionError === null);
|
|
372
|
+
const notCompiled = uncompiled.length + manualInventories;
|
|
373
|
+
console.log(`Migration incomplete: ${notCompiled} requirement(s) are not compiled, so kb_query, kb_coverage and kb_upsert do not see them, and ${skipped.length + manualLifecycle} other item(s) need a decision.`);
|
|
374
|
+
for (const finding of uncompiled) {
|
|
375
|
+
console.log(` ${finding.requirementId} (${finding.path}): status ${finding.status} is not a status Kibi knows, so kibi sync cannot compile it (${finding.extractionError}). Set status to open, in_progress or closed in the file (closed with the tag implemented for delivered work), then run kibi sync.`);
|
|
376
|
+
}
|
|
377
|
+
if (manualInventories > 0)
|
|
378
|
+
console.log(` ${manualInventories} requirement inventory(ies) need the manual fix in the warnings above; kibi sync rejects them until then.`);
|
|
379
|
+
for (const finding of skipped) {
|
|
380
|
+
console.log(` ${finding.requirementId} (${finding.path}): status ${finding.status} is not a requirement status, so the proof ladder skips it. ${finding.suggestedStatus === null ? "Set status to open, in_progress or closed in the file" : `Approve req-status-vocabulary-map-${finding.requirementId} (${finding.status} -> ${finding.suggestedStatus}) with kibi migrate --apply-safe, or set the status in the file`}.`);
|
|
381
|
+
}
|
|
382
|
+
if (manualLifecycle > 0)
|
|
383
|
+
console.log(` ${manualLifecycle} lifecycle item(s) need a person; see the warnings above.`);
|
|
384
|
+
console.log("Run 'kibi migrate' for the remaining actions; rerun 'kibi migrate --yes' after fixing them.");
|
|
385
|
+
return true;
|
|
386
|
+
}
|
|
303
387
|
export function warnMigrationRequiredWithoutYes() {
|
|
304
388
|
printWarning("Migration required for this repository.");
|
|
305
389
|
console.log("No changes applied.");
|
|
@@ -375,26 +459,43 @@ export async function migrateCommand(options = {}) {
|
|
|
375
459
|
console.error(`Unsupported schemaVersion ${configStatus.currentVersion}. Upgrade kibi-cli before migrating this KB.`);
|
|
376
460
|
return { exitCode: 1 };
|
|
377
461
|
}
|
|
462
|
+
// What the generated manifests held before this run, so the run refreshes
|
|
463
|
+
// coordinates only when it rewrote or moved the symbols manifest.
|
|
464
|
+
const generatedManifestsBefore = readGeneratedManifestBytes(cwd);
|
|
378
465
|
if (!needsStorageMigration && !needsSchemaUpgrade) {
|
|
379
466
|
const { planPolarityValueBackfill, applyPolarityValueBackfill } = await import("../operations/migration/polarity-values.js");
|
|
380
467
|
const polarityCount = options.dryRun
|
|
381
468
|
? planPolarityValueBackfill(cwd).length
|
|
382
469
|
: applyPolarityValueBackfill(cwd);
|
|
470
|
+
// Delivery statuses keep requirements out of the store at any version;
|
|
471
|
+
// map them before the drift check, which only sees compiled requirements.
|
|
472
|
+
const statuses = mapLegacyRequirementStatuses(cwd, options.dryRun === true);
|
|
383
473
|
// An advisor change can make stored inventories drift at any version,
|
|
384
474
|
// and lifecycle findings block kibi check at any version.
|
|
385
475
|
const drift = rederiveDriftedInventories(cwd, options.dryRun === true);
|
|
386
476
|
const lifecycle = repairLifecycleFindings(cwd, options.dryRun === true);
|
|
387
477
|
const legacyLinks = markLegacySymbolLinks(cwd, options.dryRun === true);
|
|
388
478
|
const rewroteSources = polarityCount > 0 ||
|
|
479
|
+
statuses.mapped > 0 ||
|
|
389
480
|
legacyLinks > 0 ||
|
|
390
481
|
drift.rederived.length > 0 ||
|
|
391
482
|
lifecycle.closed > 0 ||
|
|
392
483
|
lifecycle.rewritten > 0 ||
|
|
393
484
|
lifecycle.removed > 0;
|
|
394
|
-
if (rewroteSources ||
|
|
485
|
+
if (rewroteSources ||
|
|
486
|
+
statuses.review.length > 0 ||
|
|
487
|
+
drift.manual > 0 ||
|
|
488
|
+
lifecycle.manual > 0) {
|
|
395
489
|
if (options.dryRun !== true && rewroteSources) {
|
|
490
|
+
await refreshMigratedSymbolCoordinates(cwd, generatedManifestsBefore);
|
|
396
491
|
console.log("Run 'kibi sync' to recompile the rewritten sources.");
|
|
397
492
|
}
|
|
493
|
+
if (options.dryRun !== true)
|
|
494
|
+
printRemainingMigrationWork({
|
|
495
|
+
statuses: statuses.review,
|
|
496
|
+
manualInventories: drift.manual,
|
|
497
|
+
manualLifecycle: lifecycle.manual,
|
|
498
|
+
});
|
|
398
499
|
if (options.yes === true)
|
|
399
500
|
updateGitIgnore(cwd);
|
|
400
501
|
return { exitCode: 0 };
|
|
@@ -468,6 +569,7 @@ export async function migrateCommand(options = {}) {
|
|
|
468
569
|
console.log(`dry run: would record origin {kind: migration} on ${backfill.targets.length} authored entit(ies) without one.`);
|
|
469
570
|
}
|
|
470
571
|
}
|
|
572
|
+
mapLegacyRequirementStatuses(cwd, true);
|
|
471
573
|
rederiveDriftedInventories(cwd, true);
|
|
472
574
|
repairLifecycleFindings(cwd, true);
|
|
473
575
|
console.log(`dry run: would write migration audit metadata to ${toRelativePath(cwd, auditPath)}.`);
|
|
@@ -520,7 +622,8 @@ export async function migrateCommand(options = {}) {
|
|
|
520
622
|
const originBackfill = originBackfillStep
|
|
521
623
|
? applyOriginBackfill(cwd, migratedAt)
|
|
522
624
|
: { written: [], skipped: [], previouslyStamped: 0 };
|
|
523
|
-
|
|
625
|
+
const statuses = mapLegacyRequirementStatuses(cwd, false);
|
|
626
|
+
const drift = rederiveDriftedInventories(cwd, false);
|
|
524
627
|
const lifecycle = repairLifecycleFindings(cwd, false);
|
|
525
628
|
const supersedesUnexplained = decisionFirmnessStep
|
|
526
629
|
? planSupersedesReasonAcknowledgement(cwd)
|
|
@@ -558,6 +661,7 @@ export async function migrateCommand(options = {}) {
|
|
|
558
661
|
console.log(`Acknowledged ${supersedesUnexplained.length} supersede(s) recorded without a 'Why this changed' section; new supersedes must explain themselves.`);
|
|
559
662
|
if (firmSupersedes.length > 0)
|
|
560
663
|
console.log(`Acknowledged ${firmSupersedes.length} supersede(s) of decisions without firmness that read as firm from schema 10; a new replacement of such a decision must be firm.`);
|
|
664
|
+
await refreshMigratedSymbolCoordinates(cwd, generatedManifestsBefore);
|
|
561
665
|
const auditRecord = buildMigrationAuditRecord({
|
|
562
666
|
branch,
|
|
563
667
|
manifestPath: KB_MANIFEST_RELATIVE,
|
|
@@ -569,6 +673,7 @@ export async function migrateCommand(options = {}) {
|
|
|
569
673
|
supersededRequirementsClosed: lifecycle.closed,
|
|
570
674
|
sourcePathsRewritten: lifecycle.rewritten,
|
|
571
675
|
sourcePathsRemoved: lifecycle.removed,
|
|
676
|
+
legacyStatusesMapped: statuses.mapped,
|
|
572
677
|
preMigrationWarning: migrationWarning,
|
|
573
678
|
steps: migrationSteps.map((step) => step.id),
|
|
574
679
|
});
|
|
@@ -584,7 +689,13 @@ export async function migrateCommand(options = {}) {
|
|
|
584
689
|
printWarning(`Origin not recorded for ${skip.path}: ${skip.reason}.`);
|
|
585
690
|
}
|
|
586
691
|
console.log(`Wrote migration audit metadata to ${toRelativePath(cwd, auditPath)}.`);
|
|
587
|
-
|
|
692
|
+
const incomplete = printRemainingMigrationWork({
|
|
693
|
+
statuses: statuses.review,
|
|
694
|
+
manualInventories: drift.manual,
|
|
695
|
+
manualLifecycle: lifecycle.manual,
|
|
696
|
+
});
|
|
697
|
+
if (!incomplete)
|
|
698
|
+
console.log("Migration complete. Future 'kibi migrate' runs will be a no-op.");
|
|
588
699
|
const mergeDriverGaps = manifestMergeDriverGaps(cwd);
|
|
589
700
|
if (mergeDriverGaps !== null && mergeDriverGaps.length > 0) {
|
|
590
701
|
console.log(`Tip: kibi merge-driver resolves .kb/symbols.yaml merges by record id, but it is not wired up (${mergeDriverGaps.join("; ")}). ${MERGE_DRIVER_SETUP}`);
|
|
@@ -607,7 +718,7 @@ export async function migrateCommand(options = {}) {
|
|
|
607
718
|
// implements REQ-agent-guided-migration-orchestration, REQ-cli-schema-migration
|
|
608
719
|
export function describeMigrationRun(summary) {
|
|
609
720
|
const { audit } = summary;
|
|
610
|
-
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"}.`;
|
|
721
|
+
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}, legacy statuses mapped ${audit.legacyStatusesMapped}; .gitignore ${summary.gitignoreUpdated ? "updated" : "unchanged"}.`;
|
|
611
722
|
}
|
|
612
723
|
const KB_MANIFEST_RELATIVE = ".kb/manifest.json";
|
|
613
724
|
// implements REQ-agent-guided-migration-orchestration, REQ-cli-schema-migration
|
|
@@ -23,6 +23,24 @@ export type SyncCache = {
|
|
|
23
23
|
semanticContracts: Record<string, boolean>;
|
|
24
24
|
/** Compiler contract that produced the cached compilation; see below. */
|
|
25
25
|
compilerFingerprint?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Authored sources the last sync could not extract, keyed like `hashes`:
|
|
28
|
+
* their entities are missing from the store, so kb_status reports them.
|
|
29
|
+
*/
|
|
30
|
+
extractionFailures?: Record<string, SourceExtractionFailure>;
|
|
31
|
+
};
|
|
32
|
+
/** One authored source the last sync could not extract. */
|
|
33
|
+
export type SourceExtractionFailure = {
|
|
34
|
+
/** SHA-256 of the bytes that failed. */
|
|
35
|
+
hash: string;
|
|
36
|
+
/** The extraction error sync reported. */
|
|
37
|
+
message: string;
|
|
38
|
+
/**
|
|
39
|
+
* The source failed in the store's first compilation (or in every sync
|
|
40
|
+
* since), so it is legacy content that missed the semantic baseline, not
|
|
41
|
+
* new authoring.
|
|
42
|
+
*/
|
|
43
|
+
baseline?: boolean;
|
|
26
44
|
};
|
|
27
45
|
/**
|
|
28
46
|
* v2: cache identities are workspace-root relative instead of process-cwd
|
|
@@ -46,6 +64,18 @@ export declare const SYNC_COMPILER_FINGERPRINT: string;
|
|
|
46
64
|
* visible before the next sync repairs it.
|
|
47
65
|
*/
|
|
48
66
|
export declare function compilerFingerprintReason(storePath: string, deps?: Partial<SyncCacheDeps>): Record<string, unknown> | null;
|
|
67
|
+
/** Stale-reason code for an authored source the last sync could not extract. */
|
|
68
|
+
export declare const SOURCE_EXTRACTION_FAILED = "source_extraction_failed";
|
|
69
|
+
/**
|
|
70
|
+
* One blocking reason per authored source the last sync could not extract
|
|
71
|
+
* and that still has the bytes that failed: its entities are missing from the
|
|
72
|
+
* store, so the KB is not current even when every compiled file is. A file
|
|
73
|
+
* edited since then is reported by the changed-source reasons instead, and a
|
|
74
|
+
* deleted one by nothing.
|
|
75
|
+
*/
|
|
76
|
+
export declare function sourceExtractionFailureReasons(workspaceRoot: string, storePath: string, deps?: Partial<SyncCacheDeps>): Record<string, unknown>[];
|
|
77
|
+
/** How to make an authored source that sync cannot extract compile. */
|
|
78
|
+
export declare function sourceExtractionRemediation(file: string, message: string): string;
|
|
49
79
|
export declare function toCacheKey(workspaceRoot: string, filePath: string): string;
|
|
50
80
|
export declare function hashFile(workspaceRoot: string, filePath: string, deps?: Partial<SyncCacheDeps>): string;
|
|
51
81
|
/** Deterministically hash a JSON-compatible compiler payload. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/cache.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAO7E,UAAU,aAAa;IACrB,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,aAAa,EAAE,OAAO,aAAa,CAAC;CACrC;AAaD,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,sEAAsE;IACtE,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,iEAAiE;IACjE,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3C,kEAAkE;IAClE,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3C,yEAAyE;IACzE,mBAAmB,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -81,6 +81,64 @@ export function compilerFingerprintReason(storePath, deps) {
|
|
|
81
81
|
remediation: { command_argv: ["kibi", "sync"], applyRequired: false },
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
|
+
/** Stale-reason code for an authored source the last sync could not extract. */
|
|
85
|
+
// implements REQ-kibi-uncompiled-source-visibility
|
|
86
|
+
export const SOURCE_EXTRACTION_FAILED = "source_extraction_failed";
|
|
87
|
+
/**
|
|
88
|
+
* One blocking reason per authored source the last sync could not extract
|
|
89
|
+
* and that still has the bytes that failed: its entities are missing from the
|
|
90
|
+
* store, so the KB is not current even when every compiled file is. A file
|
|
91
|
+
* edited since then is reported by the changed-source reasons instead, and a
|
|
92
|
+
* deleted one by nothing.
|
|
93
|
+
*/
|
|
94
|
+
// implements REQ-kibi-uncompiled-source-visibility
|
|
95
|
+
export function sourceExtractionFailureReasons(workspaceRoot, storePath, deps) {
|
|
96
|
+
const resolved = resolveDeps(deps);
|
|
97
|
+
const cachePath = path.join(storePath, "sync-cache.json");
|
|
98
|
+
if (!resolved.existsSync(cachePath))
|
|
99
|
+
return [];
|
|
100
|
+
let failures;
|
|
101
|
+
try {
|
|
102
|
+
const parsed = JSON.parse(resolved.readFileSync(cachePath, "utf8"));
|
|
103
|
+
if (parsed.extractionFailures === null ||
|
|
104
|
+
typeof parsed.extractionFailures !== "object")
|
|
105
|
+
return [];
|
|
106
|
+
failures = parsed.extractionFailures;
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
const reasons = [];
|
|
112
|
+
for (const [key, failure] of Object.entries(failures).sort(([a], [b]) => a.localeCompare(b))) {
|
|
113
|
+
const absolute = path.resolve(workspaceRoot, key);
|
|
114
|
+
let current;
|
|
115
|
+
try {
|
|
116
|
+
current = hashFile(workspaceRoot, absolute, deps);
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
if (current !== failure?.hash)
|
|
122
|
+
continue;
|
|
123
|
+
const message = String(failure.message);
|
|
124
|
+
reasons.push({
|
|
125
|
+
code: SOURCE_EXTRACTION_FAILED,
|
|
126
|
+
path: key,
|
|
127
|
+
entityIds: [],
|
|
128
|
+
detail: `${key} cannot be compiled, so the entities it declares are missing from the KB: ${message}`,
|
|
129
|
+
remediation: sourceExtractionRemediation(key, message),
|
|
130
|
+
blocking: true,
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
return reasons;
|
|
134
|
+
}
|
|
135
|
+
/** How to make an authored source that sync cannot extract compile. */
|
|
136
|
+
// implements REQ-kibi-uncompiled-source-visibility
|
|
137
|
+
export function sourceExtractionRemediation(file, message) {
|
|
138
|
+
if (/\/status\b/.test(message))
|
|
139
|
+
return `Run 'kibi migrate --yes' to map a legacy requirement status (implemented, done and completed become closed with the tag implemented), or set status in ${file} to a status Kibi knows (open, in_progress or closed for a requirement); then run kibi sync.`;
|
|
140
|
+
return `Fix the front matter of ${file} named in the error (edit the file, or rewrite the entity with kb_upsert so the write replaces the failing field), then run kibi sync.`;
|
|
141
|
+
}
|
|
84
142
|
export function toCacheKey(workspaceRoot, filePath) {
|
|
85
143
|
const root = path.resolve(workspaceRoot);
|
|
86
144
|
const target = path.isAbsolute(filePath)
|
|
@@ -255,6 +313,9 @@ cachePath, deps, options = {}) {
|
|
|
255
313
|
if (parsed.compilerFingerprint !== undefined) {
|
|
256
314
|
cache.compilerFingerprint = parsed.compilerFingerprint;
|
|
257
315
|
}
|
|
316
|
+
if (parsed.extractionFailures !== undefined) {
|
|
317
|
+
cache.extractionFailures = parsed.extractionFailures;
|
|
318
|
+
}
|
|
258
319
|
return cache;
|
|
259
320
|
}
|
|
260
321
|
catch {
|
|
@@ -2,10 +2,16 @@ import { type ExtractionResult } from "../../extractors/markdown.js";
|
|
|
2
2
|
export interface ExtractionOutput {
|
|
3
3
|
results: ExtractionResult[];
|
|
4
4
|
failedCacheKeys: Set<string>;
|
|
5
|
+
/** Extraction failures, collected only in validate-only mode. */
|
|
5
6
|
errors: {
|
|
6
7
|
file: string;
|
|
7
8
|
message: string;
|
|
8
9
|
}[];
|
|
10
|
+
/** Every source that could not be extracted, in any mode. */
|
|
11
|
+
failures: {
|
|
12
|
+
file: string;
|
|
13
|
+
message: string;
|
|
14
|
+
}[];
|
|
9
15
|
}
|
|
10
16
|
/**
|
|
11
17
|
* Authored source identities are workspace-relative POSIX paths. Code symbol
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extraction.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/extraction.ts"],"names":[],"mappings":"AAuBA,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,8BAA8B,CAAC;AAGtC,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"extraction.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/extraction.ts"],"names":[],"mappings":"AAuBA,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,8BAA8B,CAAC;AAGtC,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,iEAAiE;IACjE,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5C,6DAA6D;IAC7D,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC/C;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,SAAS,gBAAgB,EAAE,EACpC,aAAa,EAAE,MAAM,GACpB,gBAAgB,EAAE,CAoBpB;AAED,UAAU,sBAAsB;IAC9B,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,gBAAgB,CAAC;IACxD,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,gBAAgB,EAAE,CAAC;CAC3D;AAOD,wBAAsB,kBAAkB,CAEtC,oBAAoB,EAAE,MAAM,EAAE,EAC9B,oBAAoB,EAAE,MAAM,EAAE,EAC9B,YAAY,EAAE,OAAO,EACrB,aAAa,SAAgB,EAC7B,YAAY,GAAE,sBAAwD,GACrE,OAAO,CAAC,gBAAgB,CAAC,CAsD3B"}
|
|
@@ -57,6 +57,7 @@ changedMarkdownFiles, changedManifestFiles, validateOnly, workspaceRoot = proces
|
|
|
57
57
|
const results = [];
|
|
58
58
|
const failedCacheKeys = new Set();
|
|
59
59
|
const errors = [];
|
|
60
|
+
const failures = [];
|
|
60
61
|
for (const file of changedMarkdownFiles) {
|
|
61
62
|
try {
|
|
62
63
|
results.push(dependencies.extractFromMarkdown(file));
|
|
@@ -74,6 +75,7 @@ changedMarkdownFiles, changedManifestFiles, validateOnly, workspaceRoot = proces
|
|
|
74
75
|
else {
|
|
75
76
|
console.warn(`Warning: Failed to extract from ${file}: ${message}`);
|
|
76
77
|
}
|
|
78
|
+
failures.push({ file, message });
|
|
77
79
|
failedCacheKeys.add(toCacheKey(workspaceRoot, file));
|
|
78
80
|
}
|
|
79
81
|
}
|
|
@@ -95,8 +97,9 @@ changedMarkdownFiles, changedManifestFiles, validateOnly, workspaceRoot = proces
|
|
|
95
97
|
else {
|
|
96
98
|
console.warn(`Warning: Failed to extract from ${file}: ${message}`);
|
|
97
99
|
}
|
|
100
|
+
failures.push({ file, message });
|
|
98
101
|
failedCacheKeys.add(toCacheKey(workspaceRoot, file));
|
|
99
102
|
}
|
|
100
103
|
}
|
|
101
|
-
return { results, failedCacheKeys, errors };
|
|
104
|
+
return { results, failedCacheKeys, errors, failures };
|
|
102
105
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA6BjE,OAAO,EAEL,yBAAyB,EAE1B,MAAM,gDAAgD,CAAC;AAGxD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,6BAA6B,CAAC;AAyBrC,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AAkCxE,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;AAmCD,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,MAAM,EACxB,4BAA4B,UAAQ,EACpC,4BAA4B,GAAE,4BAA4B,EAAO,GAChE,MAAM,EAAE,CAuGV;AAiFD,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,yBAAyB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,UAAU,kBAAkB;IAC1B,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC3E,UAAU,CAAC,EAAE,CACX,OAAO,EAAE,yBAAyB,GAAG;QAAE,UAAU,EAAE,OAAO,CAAA;KAAE,KACzD,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,aAAa,CAAC;IAC/D,yBAAyB,CAAC,EAAE,OAAO,yBAAyB,CAAC;CAC9D;AA+FD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAGvE;AAGD,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,IAAI,GAChB,IAAI,CAMN;AAED,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,UAAU,EAAE,EACzB,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,IAAI,CAIN;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,IAAI,CAMP;AAED,wBAAgB,iCAAiC,CAC/C,WAAW,EAAE,UAAU,EAAE,EACzB,oBAAoB,EAAE,OAAO,EAC7B,iBAAiB,EAAE,MAAM,EACzB,WAAW,EAAE,MAAM,GAClB,IAAI,CAUN;AAGD,wBAAsB,WAAW,CAC/B,OAAO,GAAE;IACP,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,2EAA2E;IAC3E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,uEAAuE;IACvE,KAAK,CAAC,EAAE,OAAO,CAAC;CACZ,EACN,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AA6BA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AA6BjE,OAAO,EAEL,yBAAyB,EAE1B,MAAM,gDAAgD,CAAC;AAGxD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EACL,KAAK,gBAAgB,EAGtB,MAAM,6BAA6B,CAAC;AAyBrC,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AAkCxE,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;AAmCD,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,MAAM,EACxB,4BAA4B,UAAQ,EACpC,4BAA4B,GAAE,4BAA4B,EAAO,GAChE,MAAM,EAAE,CAuGV;AAiFD,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,yBAAyB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,UAAU,kBAAkB;IAC1B,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,yBAAyB,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC3E,UAAU,CAAC,EAAE,CACX,OAAO,EAAE,yBAAyB,GAAG;QAAE,UAAU,EAAE,OAAO,CAAA;KAAE,KACzD,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,aAAa,CAAC;IAC/D,yBAAyB,CAAC,EAAE,OAAO,yBAAyB,CAAC;CAC9D;AA+FD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAGvE;AAGD,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,IAAI,GAChB,IAAI,CAMN;AAED,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,UAAU,EAAE,EACzB,QAAQ,EAAE,OAAO,EACjB,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,GACf,IAAI,CAIN;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GAAG,IAAI,CAMP;AAED,wBAAgB,iCAAiC,CAC/C,WAAW,EAAE,UAAU,EAAE,EACzB,oBAAoB,EAAE,OAAO,EAC7B,iBAAiB,EAAE,MAAM,EACzB,WAAW,EAAE,MAAM,GAClB,IAAI,CAUN;AAGD,wBAAsB,WAAW,CAC/B,OAAO,GAAE;IACP,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,2EAA2E;IAC3E,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,wEAAwE;IACxE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,uEAAuE;IACvE,KAAK,CAAC,EAAE,OAAO,CAAC;CACZ,EACN,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,UAAU,CAAC,CAstCrB;AAED,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/commands/sync.js
CHANGED
|
@@ -644,6 +644,27 @@ export async function syncCommand(options = {}, runtime = {}) {
|
|
|
644
644
|
changedManifestFiles.length === manifestFiles.length;
|
|
645
645
|
const extraction = await processExtractions(changedMarkdownFiles, changedManifestFiles, validateOnly, workspaceRoot);
|
|
646
646
|
const { failedCacheKeys, errors } = extraction;
|
|
647
|
+
// implements REQ-kibi-uncompiled-source-visibility
|
|
648
|
+
// Sources sync could not extract stay out of the store; record them so
|
|
649
|
+
// kb_status can say so. A source that failed in the store's first
|
|
650
|
+
// compilation (and in every sync since) is legacy content that missed the
|
|
651
|
+
// semantic baseline, so it keeps the baseline treatment once it compiles.
|
|
652
|
+
const previousExtractionFailures = syncCache.extractionFailures ?? {};
|
|
653
|
+
const nextExtractionFailures = {};
|
|
654
|
+
for (const failure of extraction.failures) {
|
|
655
|
+
const key = toCacheKey(workspaceRoot, failure.file);
|
|
656
|
+
const hash = nextHashes[key];
|
|
657
|
+
if (hash === undefined)
|
|
658
|
+
continue;
|
|
659
|
+
nextExtractionFailures[key] = {
|
|
660
|
+
hash,
|
|
661
|
+
message: failure.message,
|
|
662
|
+
...(initialSemanticBaseline ||
|
|
663
|
+
previousExtractionFailures[key]?.baseline === true
|
|
664
|
+
? { baseline: true }
|
|
665
|
+
: {}),
|
|
666
|
+
};
|
|
667
|
+
}
|
|
647
668
|
const extractedResults = normalizeExtractionSources(extraction.results, workspaceRoot);
|
|
648
669
|
const nextEntityHashes = {
|
|
649
670
|
...(syncCache.entityHashes ?? {}),
|
|
@@ -739,7 +760,9 @@ export async function syncCommand(options = {}, runtime = {}) {
|
|
|
739
760
|
const advertisedContract = result.entity.semantic_inventory_version !== undefined ||
|
|
740
761
|
result.entity.semantic_source_hash !== undefined ||
|
|
741
762
|
result.entity.semantic_inventory !== undefined;
|
|
742
|
-
const enforceBoundary = (!initialSemanticBaseline &&
|
|
763
|
+
const enforceBoundary = (!initialSemanticBaseline &&
|
|
764
|
+
syncCache.hashes[key] === undefined &&
|
|
765
|
+
previousExtractionFailures[key]?.baseline !== true) ||
|
|
743
766
|
syncCache.semanticContracts[key] === true ||
|
|
744
767
|
(previousSemanticHash !== undefined &&
|
|
745
768
|
previousSemanticHash !== boundary.sourceHash) ||
|
|
@@ -841,6 +864,7 @@ export async function syncCommand(options = {}, runtime = {}) {
|
|
|
841
864
|
semanticHashes: evictedSemanticHashes,
|
|
842
865
|
semanticContracts: evictedSemanticContracts,
|
|
843
866
|
compilerFingerprint: SYNC_COMPILER_FINGERPRINT,
|
|
867
|
+
extractionFailures: nextExtractionFailures,
|
|
844
868
|
});
|
|
845
869
|
info("✓ Imported 0 entities, 0 relationships (no changes)");
|
|
846
870
|
return withOptionalCommit({
|
|
@@ -990,6 +1014,7 @@ export async function syncCommand(options = {}, runtime = {}) {
|
|
|
990
1014
|
semanticHashes: evictedSemanticHashes,
|
|
991
1015
|
semanticContracts: evictedSemanticContracts,
|
|
992
1016
|
compilerFingerprint: SYNC_COMPILER_FINGERPRINT,
|
|
1017
|
+
extractionFailures: nextExtractionFailures,
|
|
993
1018
|
});
|
|
994
1019
|
published = true;
|
|
995
1020
|
if (performedFullReindex &&
|
|
@@ -1180,6 +1205,7 @@ export async function syncCommand(options = {}, runtime = {}) {
|
|
|
1180
1205
|
semanticHashes: evictedSemanticHashes,
|
|
1181
1206
|
semanticContracts: evictedSemanticContracts,
|
|
1182
1207
|
compilerFingerprint: SYNC_COMPILER_FINGERPRINT,
|
|
1208
|
+
extractionFailures: nextExtractionFailures,
|
|
1183
1209
|
});
|
|
1184
1210
|
published = true;
|
|
1185
1211
|
maybePushDocsNotIndexedDiagnostic(diagnostics, performedFullReindex, markdownFiles.length, entityCount);
|