kibi-cli 2.21.0 → 2.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli-operation-metadata.d.ts +1 -1
- package/dist/cli-operation-metadata.js +1 -1
- package/dist/cli-register-foundation.d.ts.map +1 -1
- package/dist/cli-register-foundation.js +1 -0
- package/dist/commands/check.d.ts +0 -1
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +47 -111
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +107 -5
- package/dist/commands/init-helpers.d.ts +14 -1
- package/dist/commands/init-helpers.d.ts.map +1 -1
- package/dist/commands/init-helpers.js +49 -10
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +27 -4
- package/dist/commands/legacy-storage-migration.d.ts +46 -1
- package/dist/commands/legacy-storage-migration.d.ts.map +1 -1
- package/dist/commands/legacy-storage-migration.js +244 -9
- package/dist/commands/migrate.d.ts.map +1 -1
- package/dist/commands/migrate.js +150 -166
- package/dist/commands/sync/manifest.d.ts.map +1 -1
- package/dist/commands/sync/manifest.js +9 -0
- package/dist/commands/sync/persistence.d.ts.map +1 -1
- package/dist/commands/sync/persistence.js +4 -0
- package/dist/decision-firmness.d.ts +39 -0
- package/dist/decision-firmness.d.ts.map +1 -0
- package/dist/decision-firmness.js +115 -0
- package/dist/extractors/markdown.d.ts +2 -0
- package/dist/extractors/markdown.d.ts.map +1 -1
- package/dist/extractors/markdown.js +14 -0
- package/dist/extractors/symbols-coordinator.js +1 -0
- package/dist/intent-search.d.ts.map +1 -1
- package/dist/intent-search.js +28 -6
- package/dist/operations/migration/inventory-rederive.d.ts +40 -1
- package/dist/operations/migration/inventory-rederive.d.ts.map +1 -1
- package/dist/operations/migration/inventory-rederive.js +99 -8
- package/dist/operations/migration/requirement-status.d.ts +25 -0
- package/dist/operations/migration/requirement-status.d.ts.map +1 -0
- package/dist/operations/migration/requirement-status.js +105 -0
- package/dist/operations/migration/schema6.d.ts +27 -0
- package/dist/operations/migration/schema6.d.ts.map +1 -1
- package/dist/operations/migration/schema6.js +308 -7
- package/dist/operations/migration/supersedes-reason.d.ts +26 -0
- package/dist/operations/migration/supersedes-reason.d.ts.map +1 -0
- package/dist/operations/migration/supersedes-reason.js +69 -0
- package/dist/operations/migration/symbol-legacy-links.d.ts +51 -0
- package/dist/operations/migration/symbol-legacy-links.d.ts.map +1 -0
- package/dist/operations/migration/symbol-legacy-links.js +319 -0
- package/dist/operations/modeling/predicate-applyplan.d.ts.map +1 -1
- package/dist/operations/modeling/predicate-applyplan.js +10 -2
- package/dist/operations/modeling/predicate-loader.d.ts.map +1 -1
- package/dist/operations/modeling/predicate-loader.js +11 -0
- package/dist/operations/modeling/predicate-types.d.ts +32 -1
- package/dist/operations/modeling/predicate-types.d.ts.map +1 -1
- package/dist/operations/modeling/suggest-predicates.d.ts.map +1 -1
- package/dist/operations/modeling/suggest-predicates.js +175 -35
- package/dist/operations/mutation/context-warning.d.ts +12 -2
- package/dist/operations/mutation/context-warning.d.ts.map +1 -1
- package/dist/operations/mutation/context-warning.js +6 -6
- package/dist/operations/mutation/delete.d.ts +5 -1
- package/dist/operations/mutation/delete.d.ts.map +1 -1
- package/dist/operations/mutation/delete.js +223 -17
- package/dist/operations/mutation/serialization.d.ts.map +1 -1
- package/dist/operations/mutation/serialization.js +1 -0
- package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
- package/dist/operations/mutation/source-authoring.js +130 -35
- package/dist/operations/mutation/types.d.ts +39 -1
- package/dist/operations/mutation/types.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.d.ts +17 -2
- package/dist/operations/mutation/upsert.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.js +82 -13
- package/dist/operations/mutation/validate-upsert.d.ts.map +1 -1
- package/dist/operations/mutation/validate-upsert.js +40 -8
- package/dist/operations/planning/apply-plan.d.ts +6 -1
- package/dist/operations/planning/apply-plan.d.ts.map +1 -1
- package/dist/operations/planning/apply-plan.js +26 -5
- package/dist/public/impact/diagnostics.d.ts.map +1 -1
- package/dist/public/impact/diagnostics.js +24 -14
- package/dist/public/operations/catalog.d.ts +14 -5
- package/dist/public/operations/catalog.d.ts.map +1 -1
- package/dist/public/operations/check-executor.d.ts.map +1 -1
- package/dist/public/operations/check-executor.js +6 -0
- package/dist/public/operations/contracts.d.ts.map +1 -1
- package/dist/public/operations/contracts.js +35 -2
- package/dist/public/operations/decision-firmness.d.ts +34 -0
- package/dist/public/operations/decision-firmness.d.ts.map +1 -0
- package/dist/public/operations/decision-firmness.js +216 -0
- package/dist/public/operations/discovery-executors.d.ts +2 -0
- package/dist/public/operations/discovery-executors.d.ts.map +1 -1
- package/dist/public/operations/discovery-executors.js +25 -4
- package/dist/public/operations/migration-plan.d.ts +2 -0
- package/dist/public/operations/migration-plan.d.ts.map +1 -1
- package/dist/public/operations/migration-plan.js +101 -16
- package/dist/public/operations/result-envelope.d.ts.map +1 -1
- package/dist/public/operations/result-envelope.js +27 -1
- package/dist/public/operations/specs/check-rules.generated.d.ts +1 -1
- package/dist/public/operations/specs/check-rules.generated.d.ts.map +1 -1
- package/dist/public/operations/specs/check-rules.generated.js +6 -1
- package/dist/public/operations/specs/check.d.ts +1 -1
- package/dist/public/operations/specs/mutation-schemas.d.ts +5 -0
- package/dist/public/operations/specs/mutation-schemas.d.ts.map +1 -1
- package/dist/public/operations/specs/mutation-schemas.js +5 -0
- package/dist/public/operations/specs/mutation.d.ts +6 -2
- package/dist/public/operations/specs/mutation.d.ts.map +1 -1
- package/dist/public/operations/specs/mutation.js +6 -2
- package/dist/public/operations/specs/planning.d.ts +2 -2
- package/dist/public/operations/specs/planning.js +2 -2
- package/dist/public/operations/specs/upsert.d.ts +5 -0
- package/dist/public/operations/specs/upsert.d.ts.map +1 -1
- package/dist/public/operations/symbol-granularity-check.d.ts +18 -0
- package/dist/public/operations/symbol-granularity-check.d.ts.map +1 -0
- package/dist/public/operations/symbol-granularity-check.js +175 -0
- package/dist/public/schemas/entity.d.ts.map +1 -1
- package/dist/public/schemas/entity.js +11 -0
- package/dist/public/skills/kibi-traceability/SKILL.md +6 -4
- package/dist/public/skills/kibi-usage/SKILL.md +50 -10
- package/dist/public/skills/kibi-usage/resources/source-authoring.md +4 -2
- package/dist/public/symbol-granularity.d.ts +17 -0
- package/dist/public/symbol-granularity.d.ts.map +1 -1
- package/dist/public/symbol-granularity.js +21 -0
- package/dist/relationships/shards.d.ts +10 -0
- package/dist/relationships/shards.d.ts.map +1 -1
- package/dist/relationships/shards.js +27 -11
- package/dist/schemas/entity.schema.json +28 -0
- package/dist/search-answer.d.ts +31 -2
- package/dist/search-answer.d.ts.map +1 -1
- package/dist/search-answer.js +115 -17
- package/dist/traceability/evidence-model.d.ts +7 -3
- package/dist/traceability/evidence-model.d.ts.map +1 -1
- package/dist/traceability/staged-symbols-manifest.js +6 -5
- package/dist/traceability/validate.d.ts +14 -1
- package/dist/traceability/validate.d.ts.map +1 -1
- package/dist/traceability/validate.js +41 -0
- package/dist/types/entities.d.ts +4 -0
- package/dist/types/entities.d.ts.map +1 -1
- package/dist/utils/kb-manifest.d.ts +6 -0
- package/dist/utils/kb-manifest.d.ts.map +1 -1
- package/dist/utils/kb-manifest.js +6 -0
- package/dist/utils/rule-registry.generated.d.ts +26 -0
- package/dist/utils/rule-registry.generated.d.ts.map +1 -1
- package/dist/utils/rule-registry.generated.js +31 -0
- package/dist/utils/schema-version.d.ts +1 -1
- package/dist/utils/schema-version.d.ts.map +1 -1
- package/dist/utils/schema-version.js +3 -1
- package/package.json +3 -3
- package/schema/entities.pl +6 -0
- package/src/public/impact/diagnostics.ts +29 -17
- package/src/public/operations/check-executor.ts +13 -0
- package/src/public/operations/contracts.ts +39 -2
- package/src/public/operations/decision-firmness.ts +280 -0
- package/src/public/operations/discovery-executors.ts +29 -4
- package/src/public/operations/migration-plan.ts +100 -19
- package/src/public/operations/result-envelope.ts +34 -1
- package/src/public/operations/specs/check-rules.generated.ts +6 -1
- package/src/public/operations/specs/mutation-schemas.ts +6 -0
- package/src/public/operations/specs/mutation.ts +7 -2
- package/src/public/operations/specs/planning.ts +2 -2
- package/src/public/operations/symbol-granularity-check.ts +233 -0
- package/src/public/schemas/entity.ts +12 -0
- package/src/public/skills/kibi-traceability/SKILL.md +6 -4
- package/src/public/skills/kibi-usage/SKILL.md +50 -10
- package/src/public/skills/kibi-usage/resources/source-authoring.md +4 -2
- package/src/public/symbol-granularity.ts +37 -0
- package/src/schemas/entity.schema.json +28 -0
|
@@ -17,5 +17,22 @@ export declare function isCoarseGranularityReason(value: unknown): value is Coar
|
|
|
17
17
|
export declare function getSymbolRole(candidate: GranularSymbolCandidate): SymbolRole;
|
|
18
18
|
export declare function isBehavioralSymbol(candidate: GranularSymbolCandidate): boolean;
|
|
19
19
|
export declare function getBehavioralSymbolNames(candidates: GranularSymbolCandidate[]): string[];
|
|
20
|
+
/**
|
|
21
|
+
* The candidates that are narrower than a manifest symbol: members of it
|
|
22
|
+
* (`Title.member`), or, when the source declares no symbol named like it,
|
|
23
|
+
* every other declaration in the file.
|
|
24
|
+
*/
|
|
25
|
+
export declare function narrowerSymbols<T extends {
|
|
26
|
+
name: string;
|
|
27
|
+
}>(manifestSymbolName: string, candidates: readonly T[], sourceSymbols: readonly {
|
|
28
|
+
name: string;
|
|
29
|
+
}[]): T[];
|
|
30
|
+
/**
|
|
31
|
+
* The behavioral symbols that make a traceability link on
|
|
32
|
+
* `manifestSymbolName` coarse: the staged granularity gate blocks such a
|
|
33
|
+
* link unless it carries a granularity_reason, and `kibi migrate` marks
|
|
34
|
+
* exactly these links legacy-link. Empty when the link is narrow enough.
|
|
35
|
+
*/
|
|
36
|
+
export declare function coarseLinkBehavioralNames(manifestSymbolName: string, sourceSymbols: readonly GranularSymbolCandidate[]): string[];
|
|
20
37
|
export declare function getNonBehavioralSymbolNames(candidates: GranularSymbolCandidate[]): string[];
|
|
21
38
|
//# sourceMappingURL=symbol-granularity.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"symbol-granularity.d.ts","sourceRoot":"","sources":["../../src/public/symbol-granularity.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,iCAAiC,EACjC,0BAA0B,EAC1B,wCAAwC,EACxC,gCAAgC,EAChC,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EACtB,cAAc,EACd,YAAY,EACZ,KAAK,UAAU,EACf,+BAA+B,EAC/B,KAAK,4BAA4B,EAClC,MAAM,mCAAmC,CAAC;AAK3C,OAAO,EACL,2BAA2B,EAC3B,iCAAiC,EACjC,0BAA0B,EAC1B,wCAAwC,EACxC,gCAAgC,EAChC,cAAc,EACd,YAAY,EACZ,+BAA+B,GAChC,CAAC;AACF,YAAY,EACV,uBAAuB,EACvB,iBAAiB,EACjB,UAAU,EACV,4BAA4B,GAC7B,MAAM,mCAAmC,CAAC;AAE3C,MAAM,MAAM,UAAU,GAClB,UAAU,GACV,OAAO,GACP,QAAQ,GACR,UAAU,GACV,UAAU,GACV,WAAW,GACX,MAAM,GACN,UAAU,GACV,MAAM,GACN,SAAS,CAAC;AAEd,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC;AAE1C,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAYD,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAE5D;AAED,eAAO,MAAM,uBAAuB,wBAAkB,CAAC;AAEvD,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAIhE;AAED,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,4BAA4B,CAIvC;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,iBAAiB,CAE5B;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,uBAAuB,CAElC;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,uBAAuB,GAAG,UAAU,CAI5E;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,uBAAuB,GACjC,OAAO,CAET;AAED,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,uBAAuB,EAAE,GACpC,MAAM,EAAE,CAMV;AAED,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,uBAAuB,EAAE,GACpC,MAAM,EAAE,CAQV"}
|
|
1
|
+
{"version":3,"file":"symbol-granularity.d.ts","sourceRoot":"","sources":["../../src/public/symbol-granularity.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,iCAAiC,EACjC,0BAA0B,EAC1B,wCAAwC,EACxC,gCAAgC,EAChC,KAAK,uBAAuB,EAC5B,KAAK,iBAAiB,EACtB,cAAc,EACd,YAAY,EACZ,KAAK,UAAU,EACf,+BAA+B,EAC/B,KAAK,4BAA4B,EAClC,MAAM,mCAAmC,CAAC;AAK3C,OAAO,EACL,2BAA2B,EAC3B,iCAAiC,EACjC,0BAA0B,EAC1B,wCAAwC,EACxC,gCAAgC,EAChC,cAAc,EACd,YAAY,EACZ,+BAA+B,GAChC,CAAC;AACF,YAAY,EACV,uBAAuB,EACvB,iBAAiB,EACjB,UAAU,EACV,4BAA4B,GAC7B,MAAM,mCAAmC,CAAC;AAE3C,MAAM,MAAM,UAAU,GAClB,UAAU,GACV,OAAO,GACP,QAAQ,GACR,UAAU,GACV,UAAU,GACV,WAAW,GACX,MAAM,GACN,UAAU,GACV,MAAM,GACN,SAAS,CAAC;AAEd,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC;AAE1C,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAYD,wBAAgB,eAAe,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAE5D;AAED,eAAO,MAAM,uBAAuB,wBAAkB,CAAC;AAEvD,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAIhE;AAED,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,4BAA4B,CAIvC;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,iBAAiB,CAE5B;AAED,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,uBAAuB,CAElC;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,uBAAuB,GAAG,UAAU,CAI5E;AAED,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,uBAAuB,GACjC,OAAO,CAET;AAED,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,uBAAuB,EAAE,GACpC,MAAM,EAAE,CAMV;AAED;;;;GAIG;AAEH,wBAAgB,eAAe,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EACxD,kBAAkB,EAAE,MAAM,EAC1B,UAAU,EAAE,SAAS,CAAC,EAAE,EACxB,aAAa,EAAE,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,GACzC,CAAC,EAAE,CASL;AAED;;;;;GAKG;AAEH,wBAAgB,yBAAyB,CACvC,kBAAkB,EAAE,MAAM,EAC1B,aAAa,EAAE,SAAS,uBAAuB,EAAE,GAChD,MAAM,EAAE,CAIV;AAED,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,uBAAuB,EAAE,GACpC,MAAM,EAAE,CAQV"}
|
|
@@ -37,6 +37,27 @@ export function getBehavioralSymbolNames(candidates) {
|
|
|
37
37
|
...new Set(candidates.filter(isBehavioralSymbol).map((candidate) => candidate.name)),
|
|
38
38
|
].sort();
|
|
39
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* The candidates that are narrower than a manifest symbol: members of it
|
|
42
|
+
* (`Title.member`), or, when the source declares no symbol named like it,
|
|
43
|
+
* every other declaration in the file.
|
|
44
|
+
*/
|
|
45
|
+
// implements REQ-symbol-behavioral-anchors, REQ-cli-schema-migration
|
|
46
|
+
export function narrowerSymbols(manifestSymbolName, candidates, sourceSymbols) {
|
|
47
|
+
const declared = sourceSymbols.some((symbol) => symbol.name === manifestSymbolName);
|
|
48
|
+
return candidates.filter((candidate) => candidate.name !== manifestSymbolName &&
|
|
49
|
+
(candidate.name.startsWith(`${manifestSymbolName}.`) || !declared));
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The behavioral symbols that make a traceability link on
|
|
53
|
+
* `manifestSymbolName` coarse: the staged granularity gate blocks such a
|
|
54
|
+
* link unless it carries a granularity_reason, and `kibi migrate` marks
|
|
55
|
+
* exactly these links legacy-link. Empty when the link is narrow enough.
|
|
56
|
+
*/
|
|
57
|
+
// implements REQ-symbol-behavioral-anchors, REQ-cli-schema-migration
|
|
58
|
+
export function coarseLinkBehavioralNames(manifestSymbolName, sourceSymbols) {
|
|
59
|
+
return getBehavioralSymbolNames(narrowerSymbols(manifestSymbolName, sourceSymbols, sourceSymbols));
|
|
60
|
+
}
|
|
40
61
|
export function getNonBehavioralSymbolNames(candidates) {
|
|
41
62
|
return [
|
|
42
63
|
...new Set(candidates
|
|
@@ -61,6 +61,16 @@ export type RemovedRelationshipRecords = Readonly<{
|
|
|
61
61
|
* approve the bytes before writing (deletion plans) render without writing.
|
|
62
62
|
*/
|
|
63
63
|
export declare function renderShardWithout(text: string, selectors: readonly RelationshipSelector[], shardPath: string): string;
|
|
64
|
+
export type PlannedShardRemovals = Readonly<{
|
|
65
|
+
removals: RemovedRelationshipRecords[];
|
|
66
|
+
/** Shard path -> its body without the selected records. */
|
|
67
|
+
bodies: ReadonlyMap<string, string>;
|
|
68
|
+
}>;
|
|
69
|
+
/**
|
|
70
|
+
* Render every shard that holds a selected relationship without writing it,
|
|
71
|
+
* so a dry run can report the exact bytes a delete would publish.
|
|
72
|
+
*/
|
|
73
|
+
export declare function planRelationshipShardRemovals(kbRoot: string, selectors: readonly RelationshipSelector[]): PlannedShardRemovals;
|
|
64
74
|
export declare function removeRelationshipsFromShards(kbRoot: string, selectors: readonly RelationshipSelector[]): RemovedRelationshipRecords[];
|
|
65
75
|
/**
|
|
66
76
|
* Appends a relationship to the appropriate shard.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shards.d.ts","sourceRoot":"","sources":["../../src/relationships/shards.ts"],"names":[],"mappings":"AAwBA;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGrD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGzE;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAOjE;AAED;;;GAGG;AAEH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,kBAAkB,EAAE,CAgFtB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,kBAAkB,EAAE,GAC5B,IAAI,CAON;AAwCD,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ,CAAC,CAAC;AAEH,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAAC;IAChD,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;CAClB,CAAC,CAAC;AAEH;;;GAGG;AACH;;;;GAIG;AAEH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,SAAS,oBAAoB,EAAE,EAC1C,SAAS,EAAE,MAAM,GAChB,MAAM,CA2BR;AAED,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,oBAAoB,EAAE,GACzC,0BAA0B,EAAE,
|
|
1
|
+
{"version":3,"file":"shards.d.ts","sourceRoot":"","sources":["../../src/relationships/shards.ts"],"names":[],"mappings":"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"}
|
|
@@ -197,15 +197,21 @@ export function renderShardWithout(text, selectors, shardPath) {
|
|
|
197
197
|
}
|
|
198
198
|
return document.toString();
|
|
199
199
|
}
|
|
200
|
-
|
|
200
|
+
/**
|
|
201
|
+
* Render every shard that holds a selected relationship without writing it,
|
|
202
|
+
* so a dry run can report the exact bytes a delete would publish.
|
|
203
|
+
*/
|
|
204
|
+
// implements REQ-kibi-operation-interface-parity
|
|
205
|
+
export function planRelationshipShardRemovals(kbRoot, selectors) {
|
|
201
206
|
const wanted = new Set(selectors.map((selector) => `${selector.type}\0${selector.from}\0${selector.to}`));
|
|
202
207
|
const removed = new Map();
|
|
208
|
+
const bodies = new Map();
|
|
203
209
|
for (const shardPath of listShards(kbRoot)) {
|
|
204
210
|
const records = readShard(shardPath);
|
|
205
211
|
const matching = records.filter((record) => wanted.has(`${record.type}\0${record.from}\0${record.to}`));
|
|
206
212
|
if (matching.length === 0)
|
|
207
213
|
continue;
|
|
208
|
-
|
|
214
|
+
bodies.set(shardPath, renderShardWithout(fs.readFileSync(shardPath, "utf8"), selectors, shardPath));
|
|
209
215
|
for (const record of matching) {
|
|
210
216
|
const key = `${record.type}\0${record.from}\0${record.to}`;
|
|
211
217
|
const entry = removed.get(key) ?? { paths: [], sources: [] };
|
|
@@ -214,15 +220,25 @@ export function removeRelationshipsFromShards(kbRoot, selectors) {
|
|
|
214
220
|
removed.set(key, entry);
|
|
215
221
|
}
|
|
216
222
|
}
|
|
217
|
-
return
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
selector
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
223
|
+
return {
|
|
224
|
+
bodies,
|
|
225
|
+
removals: selectors.map((selector) => {
|
|
226
|
+
const entry = removed.get(`${selector.type}\0${selector.from}\0${selector.to}`);
|
|
227
|
+
return {
|
|
228
|
+
selector,
|
|
229
|
+
shardPaths: entry?.paths ?? [],
|
|
230
|
+
sources: entry?.sources ?? [],
|
|
231
|
+
removed: entry !== undefined,
|
|
232
|
+
};
|
|
233
|
+
}),
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
export function removeRelationshipsFromShards(kbRoot, selectors) {
|
|
237
|
+
const planned = planRelationshipShardRemovals(kbRoot, selectors);
|
|
238
|
+
for (const [shardPath, body] of planned.bodies) {
|
|
239
|
+
atomicWriteText(shardPath, body);
|
|
240
|
+
}
|
|
241
|
+
return planned.removals;
|
|
226
242
|
}
|
|
227
243
|
/**
|
|
228
244
|
* Serializes records to YAML format.
|
|
@@ -514,6 +514,15 @@
|
|
|
514
514
|
},
|
|
515
515
|
"additionalProperties": false
|
|
516
516
|
},
|
|
517
|
+
"firmness": {
|
|
518
|
+
"type": "string",
|
|
519
|
+
"enum": [
|
|
520
|
+
"firm",
|
|
521
|
+
"default",
|
|
522
|
+
"exploratory"
|
|
523
|
+
],
|
|
524
|
+
"description": "Requirement and ADR only. How firmly the decision was made. firm: a human stated it as a rule; it needs a ref (origin.ref, or approval_ref on a requirement) to their words, and only a human may change it. default (assumed when absent): a delegated or agent choice; a later agent may supersede it with evidence. exploratory: a flagged guess, expected to be revisited."
|
|
525
|
+
},
|
|
517
526
|
"expects": {
|
|
518
527
|
"type": "string",
|
|
519
528
|
"enum": [
|
|
@@ -1657,6 +1666,25 @@
|
|
|
1657
1666
|
}
|
|
1658
1667
|
}
|
|
1659
1668
|
},
|
|
1669
|
+
{
|
|
1670
|
+
"if": {
|
|
1671
|
+
"properties": {
|
|
1672
|
+
"type": {
|
|
1673
|
+
"enum": [
|
|
1674
|
+
"req",
|
|
1675
|
+
"adr"
|
|
1676
|
+
]
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
},
|
|
1680
|
+
"else": {
|
|
1681
|
+
"not": {
|
|
1682
|
+
"required": [
|
|
1683
|
+
"firmness"
|
|
1684
|
+
]
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
},
|
|
1660
1688
|
{
|
|
1661
1689
|
"if": {
|
|
1662
1690
|
"properties": {
|
package/dist/search-answer.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Firmness } from "./decision-firmness.js";
|
|
1
2
|
import type { IntentSearchMatch } from "./intent-search.js";
|
|
2
3
|
import type { PrologPort } from "./public/operations/runtime-types.js";
|
|
3
4
|
/**
|
|
@@ -19,6 +20,12 @@ export type SearchAnswerEntity = Readonly<{
|
|
|
19
20
|
id: string;
|
|
20
21
|
title: string;
|
|
21
22
|
status?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Requirements and ADRs: how firmly the decision was made. `firm` (a human
|
|
25
|
+
* stated it; ask before changing), `default` (supersede it with evidence),
|
|
26
|
+
* `exploratory` (a guess to revisit).
|
|
27
|
+
*/
|
|
28
|
+
firmness?: Firmness;
|
|
22
29
|
}>;
|
|
23
30
|
/**
|
|
24
31
|
* A test verifying a governing requirement. `via` is `"direct"` for a test
|
|
@@ -69,8 +76,13 @@ export type SearchAnswerException = SearchAnswerEntity & Readonly<{
|
|
|
69
76
|
/**
|
|
70
77
|
* A linked fact says what it states in its typed form, so an agent can read
|
|
71
78
|
* `has_role(alice, admin)` or `user.role_assignment max_roles lte 2` without
|
|
72
|
-
* opening the entity, and `ask` is the
|
|
73
|
-
*
|
|
79
|
+
* opening the entity, and `ask` is the kb_query that reproduces the fact's
|
|
80
|
+
* own tuple as precisely as kb_query supports: a property or subject fact by
|
|
81
|
+
* its keys; a predicate fact by name plus, when a project `predicate_schema`
|
|
82
|
+
* or the built-in signature declares its arguments, `where` over the key
|
|
83
|
+
* arguments (the declared `key_arguments`, else the argument named `subject`,
|
|
84
|
+
* else the first), otherwise its full positional `args`. Pasted, it returns
|
|
85
|
+
* the fact and only facts sharing those key arguments.
|
|
74
86
|
*/
|
|
75
87
|
export type SearchAnswerFact = SearchAnswerEntity & Readonly<{
|
|
76
88
|
factKind?: string;
|
|
@@ -142,6 +154,23 @@ export declare const SEARCH_ANSWER_LIMITS: {
|
|
|
142
154
|
/** Characters of a witness or unknown detail kept. */
|
|
143
155
|
readonly detailChars: 240;
|
|
144
156
|
};
|
|
157
|
+
/**
|
|
158
|
+
* The declared arguments of a predicate fact's schema: a project
|
|
159
|
+
* `predicate_schema` or the built-in signature kb_query resolves `where`
|
|
160
|
+
* names against. `keyArguments` is empty when the schema declares none.
|
|
161
|
+
*/
|
|
162
|
+
export type PredicateFactSchema = Readonly<{
|
|
163
|
+
argumentNames: readonly string[];
|
|
164
|
+
keyArguments: readonly string[];
|
|
165
|
+
}>;
|
|
166
|
+
/**
|
|
167
|
+
* The `where` filter that selects the facts sharing a predicate fact's key
|
|
168
|
+
* arguments: the schema's `key_arguments`, else the argument named `subject`,
|
|
169
|
+
* else the first argument. Undefined when the schema does not fit the fact
|
|
170
|
+
* (arity) or no key argument has a value, so the caller falls back to
|
|
171
|
+
* positional args.
|
|
172
|
+
*/
|
|
173
|
+
export declare function predicateKeyFilter(args: readonly string[], schema: PredicateFactSchema): Record<string, string> | undefined;
|
|
145
174
|
/**
|
|
146
175
|
* The opening sentences of an ADR's Decision section (falling back to
|
|
147
176
|
* Rationale, then to the first prose paragraph), as plain text of at most
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-answer.d.ts","sourceRoot":"","sources":["../src/search-answer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"search-answer.d.ts","sourceRoot":"","sources":["../src/search-answer.ts"],"names":[],"mappings":"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"}
|
package/dist/search-answer.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { effectiveFirmness } from "./decision-firmness.js";
|
|
2
|
+
import { escapeAtom, normalizeEntityId, parseAtomList, parseEntityFromList, parseListOfLists, parseTriples, } from "./prolog/codec.js";
|
|
2
3
|
import { isProvenanceStub } from "./provenance-stub.js";
|
|
3
4
|
import { entityRowsGoal } from "./public/operations/discovery-entities.js";
|
|
4
5
|
import { runOperationJsonQuery } from "./public/operations/prolog-json.js";
|
|
@@ -41,6 +42,7 @@ const ROW_KEYS = [
|
|
|
41
42
|
"status",
|
|
42
43
|
"fact_kind",
|
|
43
44
|
"approved_by",
|
|
45
|
+
"firmness",
|
|
44
46
|
"source",
|
|
45
47
|
"sourceFile",
|
|
46
48
|
"predicate_namespace",
|
|
@@ -84,30 +86,68 @@ function unique(ids) {
|
|
|
84
86
|
}
|
|
85
87
|
function brief(entity) {
|
|
86
88
|
const status = text(entity.status);
|
|
89
|
+
const firmness = effectiveFirmness(entity.type, entity.firmness);
|
|
87
90
|
return {
|
|
88
91
|
id: text(entity.id),
|
|
89
92
|
title: text(entity.title),
|
|
90
93
|
...(status ? { status } : {}),
|
|
94
|
+
...(firmness ? { firmness } : {}),
|
|
91
95
|
};
|
|
92
96
|
}
|
|
93
97
|
function queryCall(args) {
|
|
94
98
|
return `kb_query(${JSON.stringify(args)})`;
|
|
95
99
|
}
|
|
100
|
+
/**
|
|
101
|
+
* The `where` filter that selects the facts sharing a predicate fact's key
|
|
102
|
+
* arguments: the schema's `key_arguments`, else the argument named `subject`,
|
|
103
|
+
* else the first argument. Undefined when the schema does not fit the fact
|
|
104
|
+
* (arity) or no key argument has a value, so the caller falls back to
|
|
105
|
+
* positional args.
|
|
106
|
+
*/
|
|
107
|
+
// implements REQ-kibi-query-fact-filters
|
|
108
|
+
export function predicateKeyFilter(args, schema) {
|
|
109
|
+
const names = schema.argumentNames;
|
|
110
|
+
if (names.length === 0 || names.length !== args.length)
|
|
111
|
+
return undefined;
|
|
112
|
+
const declared = schema.keyArguments.filter((key) => names.includes(key));
|
|
113
|
+
const keys = declared.length > 0
|
|
114
|
+
? declared
|
|
115
|
+
: [names.includes("subject") ? "subject" : names[0]];
|
|
116
|
+
const where = {};
|
|
117
|
+
for (const key of keys) {
|
|
118
|
+
const value = args[names.indexOf(key)] ?? "";
|
|
119
|
+
if (value !== "")
|
|
120
|
+
where[key] = value;
|
|
121
|
+
}
|
|
122
|
+
return Object.keys(where).length > 0 ? where : undefined;
|
|
123
|
+
}
|
|
96
124
|
/** Typed statement and follow-up query of a linked fact, by fact kind. */
|
|
97
125
|
// implements REQ-kibi-query-fact-filters
|
|
98
|
-
function factDetail(fact) {
|
|
126
|
+
function factDetail(fact, schema) {
|
|
99
127
|
const factKind = text(fact.fact_kind);
|
|
100
128
|
const base = factKind ? { factKind } : {};
|
|
101
129
|
const predicate = text(fact.predicate_name);
|
|
102
130
|
if (factKind === "predicate" && predicate) {
|
|
103
131
|
const args = Array.isArray(fact.predicate_args)
|
|
104
|
-
? fact.predicate_args.map(text)
|
|
105
|
-
:
|
|
132
|
+
? fact.predicate_args.map(text)
|
|
133
|
+
: undefined;
|
|
106
134
|
const polarity = text(fact.polarity) === "deny" ? " [deny]" : "";
|
|
135
|
+
const namespace = text(fact.predicate_namespace);
|
|
136
|
+
const call = {
|
|
137
|
+
predicate,
|
|
138
|
+
...(namespace && namespace !== "default" ? { namespace } : {}),
|
|
139
|
+
};
|
|
140
|
+
if (args !== undefined && args.length > 0) {
|
|
141
|
+
const where = schema ? predicateKeyFilter(args, schema) : undefined;
|
|
142
|
+
if (where)
|
|
143
|
+
call.where = where;
|
|
144
|
+
else
|
|
145
|
+
call.args = args.map((value) => (value === "" ? null : value));
|
|
146
|
+
}
|
|
107
147
|
return {
|
|
108
148
|
...base,
|
|
109
|
-
claim: `${predicate}(${args})${polarity}`,
|
|
110
|
-
ask: queryCall(
|
|
149
|
+
claim: `${predicate}(${args?.join(", ") ?? text(fact.predicate_args)})${polarity}`,
|
|
150
|
+
ask: queryCall(call),
|
|
111
151
|
};
|
|
112
152
|
}
|
|
113
153
|
const subjectKey = text(fact.subject_key);
|
|
@@ -128,6 +168,27 @@ function edgesGoal(ids) {
|
|
|
128
168
|
const idList = ids.map((id) => `'${escapeAtom(id)}'`).join(",");
|
|
129
169
|
return `findall([Rel,From,To], (member(Rel, [${ANSWER_RELATIONSHIPS.join(",")}]), kb_relationship(Rel, From, To), (member(From, [${idList}]); member(To, [${idList}]))), Edges)`;
|
|
130
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* For each predicate fact among `ids`, the argument names and key arguments
|
|
173
|
+
* of the schema kb_query resolves its `where` names against: the project
|
|
174
|
+
* `predicate_schema` of its namespace and name, else the built-in signature.
|
|
175
|
+
* Facts of other kinds, and predicates without a schema, yield no row.
|
|
176
|
+
*/
|
|
177
|
+
// implements REQ-kibi-query-fact-filters
|
|
178
|
+
function factSchemasGoal(ids) {
|
|
179
|
+
const idList = ids.map((id) => `'${escapeAtom(id)}'`).join(",");
|
|
180
|
+
return `findall([FactId,Names,Keys], (member(FactId, [${idList}]), kb:predicate_fact(FactId, Ns, Name, _, _), ((kb:predicate_schema(SchemaId, Ns, Name, _, Names, _) -> ((kb_entity(SchemaId, fact, Props), memberchk(key_arguments=KeysRaw, Props), kb:normalize_term_atom_list(KeysRaw, Keys)) -> true ; Keys = [])) ; (kb:builtin_decision_predicate(Ns, Name, _, KeyPositions, _), kb:builtin_predicate_signature(Name, _, Names), findall(Key, (member(P, KeyPositions), nth1(P, Names, Key)), Keys)))), Schemas)`;
|
|
181
|
+
}
|
|
182
|
+
function parseFactSchemas(raw) {
|
|
183
|
+
const schemas = new Map();
|
|
184
|
+
for (const [id, names, keys] of parseTriples(raw ?? "[]")) {
|
|
185
|
+
schemas.set(normalizeEntityId(id), {
|
|
186
|
+
argumentNames: parseAtomList(names),
|
|
187
|
+
keyArguments: parseAtomList(keys),
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
return schemas;
|
|
191
|
+
}
|
|
131
192
|
/**
|
|
132
193
|
* The part of the KB graph the answer reads, fetched in batches: each
|
|
133
194
|
* `fetch` is one engine round trip for every id whose edges or row are not
|
|
@@ -489,6 +550,29 @@ async function fetchVerdicts(prolog, graph, rowIds, reqIds) {
|
|
|
489
550
|
return undefined;
|
|
490
551
|
}
|
|
491
552
|
}
|
|
553
|
+
/**
|
|
554
|
+
* The rows the answer still needs plus the schemas of the predicate facts
|
|
555
|
+
* among `factIds`, in one round trip. A schema lookup the engine cannot run
|
|
556
|
+
* leaves the rows loaded and every ask positional.
|
|
557
|
+
*/
|
|
558
|
+
// implements REQ-kibi-query-fact-filters
|
|
559
|
+
async function fetchFactSchemas(graph, factIds, request) {
|
|
560
|
+
if (factIds.length === 0) {
|
|
561
|
+
await graph.fetch(request);
|
|
562
|
+
return new Map();
|
|
563
|
+
}
|
|
564
|
+
try {
|
|
565
|
+
const bindings = await graph.fetch({
|
|
566
|
+
...request,
|
|
567
|
+
alsoGoal: factSchemasGoal(factIds),
|
|
568
|
+
});
|
|
569
|
+
return parseFactSchemas(bindings.Schemas);
|
|
570
|
+
}
|
|
571
|
+
catch {
|
|
572
|
+
await graph.fetch(request);
|
|
573
|
+
return new Map();
|
|
574
|
+
}
|
|
575
|
+
}
|
|
492
576
|
// implements REQ-bootstrap-provenance-stubs
|
|
493
577
|
export async function buildSearchAnswer(prolog, matches, options = {}) {
|
|
494
578
|
const limits = SEARCH_ANSWER_LIMITS;
|
|
@@ -551,13 +635,9 @@ export async function buildSearchAnswer(prolog, matches, options = {}) {
|
|
|
551
635
|
continue;
|
|
552
636
|
}
|
|
553
637
|
if (owners.length === 0 && ["fact", "scenario", "symbol"].includes(type)) {
|
|
638
|
+
// A fact's claim and ask are filled in once its schema is known.
|
|
554
639
|
if (ungoverned.length < limits.ungoverned)
|
|
555
|
-
ungoverned.push({
|
|
556
|
-
...brief(entity),
|
|
557
|
-
...(type === "fact" ? factDetail(entity) : {}),
|
|
558
|
-
type,
|
|
559
|
-
rank: index + 1,
|
|
560
|
-
});
|
|
640
|
+
ungoverned.push({ ...brief(entity), type, rank: index + 1 });
|
|
561
641
|
else
|
|
562
642
|
truncated = true;
|
|
563
643
|
continue;
|
|
@@ -689,7 +769,13 @@ export async function buildSearchAnswer(prolog, matches, options = {}) {
|
|
|
689
769
|
exceptions: firstOf(into("exempts")),
|
|
690
770
|
};
|
|
691
771
|
});
|
|
692
|
-
|
|
772
|
+
// The schemas of the linked and ungoverned predicate facts share this
|
|
773
|
+
// round trip, so each fact's ask can name its key arguments.
|
|
774
|
+
const factIds = unique([
|
|
775
|
+
...ungoverned.filter((entry) => entry.type === "fact").map((e) => e.id),
|
|
776
|
+
...plans.flatMap((plan) => plan.facts),
|
|
777
|
+
]);
|
|
778
|
+
const schemas = await fetchFactSchemas(graph, factIds, {
|
|
693
779
|
edges: plans.flatMap((plan) => plan.scenarios),
|
|
694
780
|
rows: plans.flatMap((plan) => [
|
|
695
781
|
...plan.facts,
|
|
@@ -699,6 +785,18 @@ export async function buildSearchAnswer(prolog, matches, options = {}) {
|
|
|
699
785
|
...plan.directTests.slice(0, limits.perRequirement),
|
|
700
786
|
]),
|
|
701
787
|
});
|
|
788
|
+
const detailedUngoverned = ungoverned.map((entry) => {
|
|
789
|
+
const row = entry.type === "fact" ? graph.row(entry.id) : null;
|
|
790
|
+
if (row === null)
|
|
791
|
+
return entry;
|
|
792
|
+
const { type, rank } = entry;
|
|
793
|
+
return {
|
|
794
|
+
...brief(row),
|
|
795
|
+
...factDetail(row, schemas.get(entry.id)),
|
|
796
|
+
type,
|
|
797
|
+
rank,
|
|
798
|
+
};
|
|
799
|
+
});
|
|
702
800
|
// Tests linked to the requirement itself come first, then tests that
|
|
703
801
|
// verify one of its scenarios; a test reached both ways counts as direct.
|
|
704
802
|
const testVias = plans.map((plan) => {
|
|
@@ -738,7 +836,7 @@ export async function buildSearchAnswer(prolog, matches, options = {}) {
|
|
|
738
836
|
via: req.via,
|
|
739
837
|
facts: rowsOf(plan.facts).map((fact) => ({
|
|
740
838
|
...brief(fact),
|
|
741
|
-
...factDetail(fact),
|
|
839
|
+
...factDetail(fact, schemas.get(text(fact.id))),
|
|
742
840
|
})),
|
|
743
841
|
scenarios: rowsOf(plan.scenarios).map(brief),
|
|
744
842
|
tests: rowsOf(testIds[index] ?? []).map((row) => ({
|
|
@@ -769,17 +867,17 @@ export async function buildSearchAnswer(prolog, matches, options = {}) {
|
|
|
769
867
|
? verdicts.scope.syncedAt
|
|
770
868
|
: null,
|
|
771
869
|
};
|
|
772
|
-
|
|
870
|
+
detailedUngoverned.sort((left, right) => left.rank - right.rank);
|
|
773
871
|
const answer = {
|
|
774
872
|
version: "kibi.search-answer.v1",
|
|
775
873
|
governing,
|
|
776
874
|
rationale,
|
|
777
875
|
notGoverning,
|
|
778
876
|
observations: observations.slice(0, limits.observations),
|
|
779
|
-
ungoverned,
|
|
877
|
+
ungoverned: detailedUngoverned,
|
|
780
878
|
scope,
|
|
781
879
|
truncated: truncated || graph.truncated,
|
|
782
|
-
note: answerNote(governing.length,
|
|
880
|
+
note: answerNote(governing.length, detailedUngoverned),
|
|
783
881
|
};
|
|
784
882
|
return fitSearchAnswer(answer, limits.maxBytes);
|
|
785
883
|
}
|
|
@@ -61,14 +61,18 @@ export interface KibiImpactSymbolsManifestFileDetail {
|
|
|
61
61
|
path: string;
|
|
62
62
|
/** Symbol count extraction finds in the staged source content. */
|
|
63
63
|
expectedCount: number;
|
|
64
|
-
/**
|
|
64
|
+
/**
|
|
65
|
+
* Extracted symbols that have a matching staged manifest+coordinates entry
|
|
66
|
+
* (`expectedCount - missing.length`); evidence-only entries in `extra` are
|
|
67
|
+
* not counted.
|
|
68
|
+
*/
|
|
65
69
|
coveredCount: number;
|
|
66
|
-
/**
|
|
70
|
+
/** Every extracted symbol with no evidence entry (title + definition line). */
|
|
67
71
|
missing: Array<{
|
|
68
72
|
title: string;
|
|
69
73
|
line: number;
|
|
70
74
|
}>;
|
|
71
|
-
/**
|
|
75
|
+
/** Every evidence entry the extractor no longer finds at the recorded shape. */
|
|
72
76
|
extra: string[];
|
|
73
77
|
}
|
|
74
78
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"evidence-model.d.ts","sourceRoot":"","sources":["../../src/traceability/evidence-model.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,+BAA+B,iDACI,CAAC;AAEjD,eAAO,MAAM,sBAAsB,0BAA0B,CAAC;AAE9D,+EAA+E;AAC/E,eAAO,MAAM,0BAA0B,qBAAqB,CAAC;AAE7D,qFAAqF;AACrF,eAAO,MAAM,4BAA4B,gCAAgC,CAAC;AAE1E,mEAAmE;AACnE,eAAO,MAAM,0BAA0B,sBAAsB,CAAC;AAE9D,oEAAoE;AACpE,MAAM,MAAM,cAAc,GACtB,KAAK,GACL,UAAU,GACV,MAAM,GACN,KAAK,GACL,MAAM,GACN,OAAO,GACP,QAAQ,GACR,MAAM,CAAC;AAEX;;;;;;;GAOG;AACH,MAAM,MAAM,gBAAgB,GACxB,sBAAsB,GACtB,0BAA0B,CAAC;AAE/B,sEAAsE;AACtE,MAAM,WAAW,sBAAsB;IACrC,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,IAAI,EAAE,gBAAgB,CAAC;CACxB;AAED;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,wEAAwE;IACxE,IAAI,EAAE,iBAAiB,GAAG,kBAAkB,CAAC;IAC7C,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,2DAA2D;IAC3D,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,sEAAsE;IACtE,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,mCAAmC;IAClD,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,aAAa,EAAE,MAAM,CAAC;IACtB
|
|
1
|
+
{"version":3,"file":"evidence-model.d.ts","sourceRoot":"","sources":["../../src/traceability/evidence-model.ts"],"names":[],"mappings":"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"}
|
|
@@ -264,8 +264,7 @@ function getEffectiveManifestRecords(options) {
|
|
|
264
264
|
stagedCoordinateArtifact,
|
|
265
265
|
};
|
|
266
266
|
}
|
|
267
|
-
|
|
268
|
-
const MAX_DETAIL_ITEMS = 6;
|
|
267
|
+
// implements REQ-cli-staged-impact-enforcement
|
|
269
268
|
function diffSymbolEvidence(sourcePath, expectedSymbols, stagedSymbols) {
|
|
270
269
|
const stagedTitles = new Set(stagedSymbols.map((symbol) => symbol.title));
|
|
271
270
|
const expectedTitles = new Set(expectedSymbols.map((symbol) => symbol.title));
|
|
@@ -282,12 +281,14 @@ function diffSymbolEvidence(sourcePath, expectedSymbols, stagedSymbols) {
|
|
|
282
281
|
if (missing.length === 0 && extra.length === 0) {
|
|
283
282
|
return null;
|
|
284
283
|
}
|
|
284
|
+
// Keep the complete lists: human-facing renderers truncate (with an
|
|
285
|
+
// accurate "… and N more"), while JSON evidence carries every name.
|
|
285
286
|
return {
|
|
286
287
|
path: sourcePath,
|
|
287
288
|
expectedCount: expectedSymbols.length,
|
|
288
|
-
coveredCount:
|
|
289
|
-
missing
|
|
290
|
-
extra
|
|
289
|
+
coveredCount: expectedSymbols.length - missing.length,
|
|
290
|
+
missing,
|
|
291
|
+
extra,
|
|
291
292
|
};
|
|
292
293
|
}
|
|
293
294
|
export function assessStagedSymbolsManifest(options) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type PrologProcess } from "../prolog.js";
|
|
2
|
+
import { type ParsedViolation } from "../prolog/codec.js";
|
|
2
3
|
export interface ValidationOptions {
|
|
3
4
|
minLinks: number;
|
|
4
5
|
prolog: PrologProcess;
|
|
@@ -17,6 +18,18 @@ declare function splitTopLevelComma(s: string): string[];
|
|
|
17
18
|
declare function splitTopLevelLists(value: string): string[];
|
|
18
19
|
declare function parsePrologListOfLists(value: string): string[][];
|
|
19
20
|
export declare function validateStagedSymbols(options: ValidationOptions): Promise<Violation[]>;
|
|
21
|
+
/**
|
|
22
|
+
* Full-check `symbol-coverage` for the staged change set: the changed source
|
|
23
|
+
* symbols in the consulted overlay plus `extraSymbolIds` (symbols whose staged
|
|
24
|
+
* manifest entry changed). The Prolog rule is the one `kibi check` runs, so a
|
|
25
|
+
* commit cannot pass the staged gate with coverage the full check rejects.
|
|
26
|
+
*/
|
|
27
|
+
export declare function validateStagedSymbolCoverage(options: {
|
|
28
|
+
prolog: PrologProcess;
|
|
29
|
+
extraSymbolIds?: readonly string[];
|
|
30
|
+
}): Promise<ParsedViolation[]>;
|
|
31
|
+
/** Text lines for staged symbol-coverage violations, in `kibi check` form. */
|
|
32
|
+
export declare function formatCoverageViolations(violations: readonly ParsedViolation[]): string;
|
|
20
33
|
export declare function formatViolations(violations: Violation[]): string;
|
|
21
34
|
export declare const __test__: {
|
|
22
35
|
unquoteAtom: typeof unquoteAtom;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/traceability/validate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/traceability/validate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,aAAa,EAAmB,MAAM,cAAc,CAAC;AACnE,OAAO,EACL,KAAK,eAAe,EAIrB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,iBAAS,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAO1C;AAED,iBAAS,kBAAkB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CA0B/C;AAED,iBAAS,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CA8CnD;AAED,iBAAS,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,CAuBzD;AAGD,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,SAAS,EAAE,CAAC,CAgDtB;AAED;;;;;GAKG;AAEH,wBAAsB,4BAA4B,CAAC,OAAO,EAAE;IAC1D,MAAM,EAAE,aAAa,CAAC;IACtB,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAgB7B;AAED,8EAA8E;AAE9E,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,SAAS,eAAe,EAAE,GACrC,MAAM,CAaR;AAED,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CAkBhE;AAGD,eAAO,MAAM,QAAQ;;;;;CAKpB,CAAC"}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { resolveKbPlPath } from "../prolog.js";
|
|
3
|
+
import { escapeAtom, parseViolationRows, toPrologAtom, } from "../prolog/codec.js";
|
|
1
4
|
function unquoteAtom(value) {
|
|
2
5
|
// remove surrounding single quotes and unescape doubled quotes
|
|
3
6
|
const trimmed = value.trim();
|
|
@@ -141,6 +144,44 @@ export async function validateStagedSymbols(options) {
|
|
|
141
144
|
}
|
|
142
145
|
return violations;
|
|
143
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* Full-check `symbol-coverage` for the staged change set: the changed source
|
|
149
|
+
* symbols in the consulted overlay plus `extraSymbolIds` (symbols whose staged
|
|
150
|
+
* manifest entry changed). The Prolog rule is the one `kibi check` runs, so a
|
|
151
|
+
* commit cannot pass the staged gate with coverage the full check rejects.
|
|
152
|
+
*/
|
|
153
|
+
// implements REQ-014
|
|
154
|
+
export async function validateStagedSymbolCoverage(options) {
|
|
155
|
+
const extra = `[${[...new Set(options.extraSymbolIds ?? [])]
|
|
156
|
+
.sort()
|
|
157
|
+
.map(toPrologAtom)
|
|
158
|
+
.join(",")}]`;
|
|
159
|
+
const checksPl = escapeAtom(path.join(path.dirname(resolveKbPlPath()), "checks.pl"));
|
|
160
|
+
const goal = `(use_module('${checksPl}'), call(checks:check_changed_symbol_coverage(${extra}, Violations)))`;
|
|
161
|
+
const res = await options.prolog.query(goal);
|
|
162
|
+
if (!res.success) {
|
|
163
|
+
throw new Error(`Prolog symbol-coverage query failed: ${res.error || "unknown error"}`);
|
|
164
|
+
}
|
|
165
|
+
return parseViolationRows(res.bindings.Violations ?? "[]");
|
|
166
|
+
}
|
|
167
|
+
/** Text lines for staged symbol-coverage violations, in `kibi check` form. */
|
|
168
|
+
// implements REQ-014
|
|
169
|
+
export function formatCoverageViolations(violations) {
|
|
170
|
+
if (violations.length === 0)
|
|
171
|
+
return "";
|
|
172
|
+
const lines = [
|
|
173
|
+
`Found ${violations.length} symbol-coverage violation(s) in staged symbols (the same rule kibi check runs):`,
|
|
174
|
+
];
|
|
175
|
+
for (const violation of violations) {
|
|
176
|
+
lines.push("", `[${violation.rule}] ${violation.entityId}`);
|
|
177
|
+
if (violation.source)
|
|
178
|
+
lines.push(` Source: ${violation.source}`);
|
|
179
|
+
lines.push(` ${violation.description}`);
|
|
180
|
+
if (violation.suggestion)
|
|
181
|
+
lines.push(` Suggestion: ${violation.suggestion}`);
|
|
182
|
+
}
|
|
183
|
+
return lines.join("\n");
|
|
184
|
+
}
|
|
144
185
|
export function formatViolations(violations) {
|
|
145
186
|
// implements REQ-014
|
|
146
187
|
if (!violations || violations.length === 0)
|