kibi-cli 2.2.0 → 2.4.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-json-command.d.ts.map +1 -1
- package/dist/cli-json-command.js +2 -2
- package/dist/cli-operation-loader.d.ts.map +1 -1
- package/dist/cli-operation-loader.js +3 -0
- package/dist/cli-operation-metadata.d.ts +5 -1
- package/dist/cli-operation-metadata.d.ts.map +1 -1
- package/dist/cli-operation-metadata.js +6 -1
- package/dist/cli-register-maintenance.d.ts.map +1 -1
- package/dist/cli-register-maintenance.js +7 -0
- package/dist/cli-register-reporting.d.ts.map +1 -1
- package/dist/cli-register-reporting.js +4 -0
- package/dist/commands/check-diff.d.ts +5 -0
- package/dist/commands/check-diff.d.ts.map +1 -0
- package/dist/commands/check-diff.js +62 -0
- package/dist/commands/check-generated.d.ts.map +1 -1
- package/dist/commands/check-generated.js +41 -18
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +210 -73
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +63 -29
- package/dist/commands/github-init.d.ts.map +1 -1
- package/dist/commands/github-init.js +9 -2
- package/dist/commands/merge-driver.d.ts +31 -0
- package/dist/commands/merge-driver.d.ts.map +1 -0
- package/dist/commands/merge-driver.js +268 -0
- package/dist/commands/sync/manifest.d.ts.map +1 -1
- package/dist/commands/sync/manifest.js +3 -1
- package/dist/engine.d.ts +15 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +252 -52
- package/dist/extractors/symbols-coordinator.d.ts +7 -0
- package/dist/extractors/symbols-coordinator.d.ts.map +1 -1
- package/dist/extractors/symbols-coordinator.js +75 -39
- package/dist/operations/bootstrap/candidates.js +1 -1
- package/dist/operations/bootstrap/discovery.js +1 -1
- package/dist/operations/bootstrap/generate.d.ts.map +1 -1
- package/dist/operations/bootstrap/generate.js +21 -5
- package/dist/operations/bootstrap/guidance-actions.d.ts.map +1 -1
- package/dist/operations/bootstrap/guidance-actions.js +3 -0
- package/dist/operations/bootstrap/guidance.d.ts.map +1 -1
- package/dist/operations/bootstrap/guidance.js +7 -1
- package/dist/operations/bootstrap/intent-claims.d.ts +17 -0
- package/dist/operations/bootstrap/intent-claims.d.ts.map +1 -0
- package/dist/operations/bootstrap/intent-claims.js +95 -0
- package/dist/operations/bootstrap/presentation.d.ts +2 -0
- package/dist/operations/bootstrap/presentation.d.ts.map +1 -1
- package/dist/operations/bootstrap/presentation.js +60 -1
- package/dist/operations/bootstrap/types.d.ts +28 -0
- package/dist/operations/bootstrap/types.d.ts.map +1 -1
- package/dist/operations/bootstrap/types.js +16 -0
- package/dist/operations/modeling/predicate-inference-1.js +1 -1
- package/dist/operations/mutation/source-authoring.d.ts.map +1 -1
- package/dist/operations/mutation/source-authoring.js +175 -53
- package/dist/operations/mutation/symbol-refresh.d.ts.map +1 -1
- package/dist/operations/mutation/symbol-refresh.js +4 -1
- package/dist/operations/mutation/upsert.d.ts.map +1 -1
- package/dist/operations/mutation/upsert.js +5 -7
- package/dist/operations/planning/apply-plan.d.ts.map +1 -1
- package/dist/operations/planning/apply-plan.js +5 -9
- package/dist/operations/proof/ingest-proof.d.ts.map +1 -1
- package/dist/operations/proof/ingest-proof.js +1 -0
- package/dist/operations/semantic-advisor/analysis-receipt.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/analysis-receipt.js +7 -1
- package/dist/operations/semantic-advisor/analyze-prose.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/analyze-prose.js +26 -4
- package/dist/operations/semantic-advisor/clauses.d.ts +1 -0
- package/dist/operations/semantic-advisor/clauses.d.ts.map +1 -1
- package/dist/operations/semantic-advisor/clauses.js +7 -1
- package/dist/performance-trace.d.ts +17 -0
- package/dist/performance-trace.d.ts.map +1 -0
- package/dist/performance-trace.js +134 -0
- package/dist/plugins/approved-source-analyzers.d.ts +13 -0
- package/dist/plugins/approved-source-analyzers.d.ts.map +1 -0
- package/dist/plugins/approved-source-analyzers.generated.d.ts +71 -0
- package/dist/plugins/approved-source-analyzers.generated.d.ts.map +1 -0
- package/dist/plugins/approved-source-analyzers.generated.js +77 -0
- package/dist/plugins/approved-source-analyzers.js +3 -0
- package/dist/plugins/maintenance-source-analysis.d.ts +14 -0
- package/dist/plugins/maintenance-source-analysis.d.ts.map +1 -0
- package/dist/plugins/maintenance-source-analysis.js +191 -0
- package/dist/plugins/registry.d.ts +2 -1
- package/dist/plugins/registry.d.ts.map +1 -1
- package/dist/plugins/registry.js +6 -1
- package/dist/plugins/source-analysis-service.d.ts +36 -1
- package/dist/plugins/source-analysis-service.d.ts.map +1 -1
- package/dist/plugins/source-analysis-service.js +184 -27
- package/dist/plugins/source-change-analysis.d.ts +15 -0
- package/dist/plugins/source-change-analysis.d.ts.map +1 -0
- package/dist/plugins/source-change-analysis.js +54 -0
- package/dist/plugins/source-classification.d.ts +41 -0
- package/dist/plugins/source-classification.d.ts.map +1 -0
- package/dist/plugins/source-classification.js +490 -0
- package/dist/prolog/swipl-resolver.d.ts +88 -0
- package/dist/prolog/swipl-resolver.d.ts.map +1 -0
- package/dist/prolog/swipl-resolver.js +446 -0
- package/dist/prolog.d.ts +15 -1
- package/dist/prolog.d.ts.map +1 -1
- package/dist/prolog.js +67 -6
- package/dist/public/diagnostic-usage.d.ts +14 -0
- package/dist/public/diagnostic-usage.d.ts.map +1 -1
- package/dist/public/diagnostic-usage.js +55 -1
- package/dist/public/impact/analyzer.d.ts.map +1 -1
- package/dist/public/impact/analyzer.js +56 -5
- package/dist/public/impact/diagnostics.d.ts.map +1 -1
- package/dist/public/impact/diagnostics.js +3 -1
- package/dist/public/impact/manifest.d.ts.map +1 -1
- package/dist/public/impact/manifest.js +15 -1
- package/dist/public/impact/source-changes.d.ts.map +1 -1
- package/dist/public/impact/source-changes.js +35 -27
- package/dist/public/impact/types.d.ts +2 -0
- package/dist/public/impact/types.d.ts.map +1 -1
- package/dist/public/operations/catalog.d.ts +117 -1
- package/dist/public/operations/catalog.d.ts.map +1 -1
- package/dist/public/operations/catalog.js +2 -0
- package/dist/public/operations/contracts.d.ts.map +1 -1
- package/dist/public/operations/contracts.js +309 -8
- package/dist/public/operations/impact-review-preparation.d.ts +14 -0
- package/dist/public/operations/impact-review-preparation.d.ts.map +1 -0
- package/dist/public/operations/impact-review-preparation.js +379 -0
- package/dist/public/operations/index.d.ts +2 -0
- package/dist/public/operations/index.d.ts.map +1 -1
- package/dist/public/operations/index.js +2 -0
- package/dist/public/operations/node-ports.d.ts.map +1 -1
- package/dist/public/operations/node-ports.js +1 -35
- package/dist/public/operations/proof-receipt-projection.d.ts +5 -0
- package/dist/public/operations/proof-receipt-projection.d.ts.map +1 -0
- package/dist/public/operations/proof-receipt-projection.js +36 -0
- package/dist/public/operations/specs/bootstrap.d.ts +73 -1
- package/dist/public/operations/specs/bootstrap.d.ts.map +1 -1
- package/dist/public/operations/specs/bootstrap.js +66 -1
- package/dist/public/operations/specs/impact-review-preparation.d.ts +47 -0
- package/dist/public/operations/specs/impact-review-preparation.d.ts.map +1 -0
- package/dist/public/operations/specs/impact-review-preparation.js +43 -0
- package/dist/public/operations/symbol-repair-plan.d.ts.map +1 -1
- package/dist/public/operations/symbol-repair-plan.js +3 -1
- package/dist/public/operations/types.d.ts +1 -1
- package/dist/public/operations/types.d.ts.map +1 -1
- package/dist/public/skills/kibi-bootstrap/SKILL.md +47 -11
- package/dist/public/skills/kibi-bootstrap/resources/bootstrap.md +6 -1
- package/dist/public/skills/kibi-usage/SKILL.md +14 -0
- package/dist/public/skills/kibi-usage/resources/operation-access.md +5 -0
- package/dist/public/telemetry-acceptance.d.ts +8 -0
- package/dist/public/telemetry-acceptance.d.ts.map +1 -1
- package/dist/public/telemetry-acceptance.js +10 -0
- package/dist/traceability/analysis-gate.d.ts +39 -0
- package/dist/traceability/analysis-gate.d.ts.map +1 -0
- package/dist/traceability/analysis-gate.js +51 -0
- package/dist/traceability/git-change-snapshot.d.ts +27 -0
- package/dist/traceability/git-change-snapshot.d.ts.map +1 -0
- package/dist/traceability/git-change-snapshot.js +411 -0
- package/dist/traceability/git-staged.d.ts +5 -1
- package/dist/traceability/git-staged.d.ts.map +1 -1
- package/dist/traceability/git-staged.js +16 -11
- package/dist/traceability/impact-evaluator.d.ts +54 -0
- package/dist/traceability/impact-evaluator.d.ts.map +1 -0
- package/dist/traceability/impact-evaluator.js +270 -0
- package/dist/traceability/impact-git-tree.d.ts +12 -0
- package/dist/traceability/impact-git-tree.d.ts.map +1 -0
- package/dist/traceability/impact-git-tree.js +46 -0
- package/dist/traceability/impact-knowledge.d.ts +16 -0
- package/dist/traceability/impact-knowledge.d.ts.map +1 -0
- package/dist/traceability/impact-knowledge.js +165 -0
- package/dist/traceability/impact-policy.d.ts +15 -0
- package/dist/traceability/impact-policy.d.ts.map +1 -0
- package/dist/traceability/impact-policy.js +48 -0
- package/dist/traceability/impact-policy.v1.schema.json +48 -0
- package/dist/traceability/impact-pr-diff.d.ts +5 -0
- package/dist/traceability/impact-pr-diff.d.ts.map +1 -0
- package/dist/traceability/impact-pr-diff.js +83 -0
- package/dist/traceability/impact-record-validation.d.ts +9 -0
- package/dist/traceability/impact-record-validation.d.ts.map +1 -0
- package/dist/traceability/impact-record-validation.js +113 -0
- package/dist/traceability/impact-review.d.ts +148 -0
- package/dist/traceability/impact-review.d.ts.map +1 -0
- package/dist/traceability/impact-review.js +494 -0
- package/dist/traceability/impact-review.schema.json +365 -0
- package/dist/traceability/impact-side-evidence.d.ts +13 -0
- package/dist/traceability/impact-side-evidence.d.ts.map +1 -0
- package/dist/traceability/impact-side-evidence.js +240 -0
- package/dist/traceability/reviewed-coordinate-refresh.d.ts +10 -0
- package/dist/traceability/reviewed-coordinate-refresh.d.ts.map +1 -0
- package/dist/traceability/reviewed-coordinate-refresh.js +49 -0
- package/dist/traceability/snapshot-knowledge.d.ts +4 -0
- package/dist/traceability/snapshot-knowledge.d.ts.map +1 -0
- package/dist/traceability/snapshot-knowledge.js +98 -0
- package/dist/traceability/staged-file-coverage.d.ts +23 -0
- package/dist/traceability/staged-file-coverage.d.ts.map +1 -1
- package/dist/traceability/staged-impact-contract.d.ts.map +1 -1
- package/dist/traceability/staged-impact-contract.js +2 -16
- package/dist/traceability/staged-symbols-manifest.d.ts +4 -0
- package/dist/traceability/staged-symbols-manifest.d.ts.map +1 -1
- package/dist/traceability/staged-symbols-manifest.js +17 -6
- package/dist/traceability/symbol-extract.d.ts +3 -5
- package/dist/traceability/symbol-extract.d.ts.map +1 -1
- package/dist/traceability/symbol-extract.js +49 -34
- package/dist/traceability/temp-kb.d.ts +1 -1
- package/dist/traceability/temp-kb.d.ts.map +1 -1
- package/dist/traceability/temp-kb.js +49 -13
- package/dist/traceability/trusted-pr-event.d.ts +13 -0
- package/dist/traceability/trusted-pr-event.d.ts.map +1 -0
- package/dist/traceability/trusted-pr-event.js +105 -0
- package/dist/utils/canonical-path.d.ts +3 -0
- package/dist/utils/canonical-path.d.ts.map +1 -0
- package/dist/utils/canonical-path.js +33 -0
- package/package.json +14 -5
- package/src/public/diagnostic-usage.ts +59 -1
- package/src/public/impact/analyzer.ts +88 -5
- package/src/public/impact/diagnostics.ts +7 -5
- package/src/public/impact/manifest.ts +14 -1
- package/src/public/impact/source-changes.ts +39 -34
- package/src/public/impact/types.ts +5 -0
- package/src/public/operations/catalog.ts +2 -0
- package/src/public/operations/contracts.ts +385 -9
- package/src/public/operations/impact-review-preparation.ts +548 -0
- package/src/public/operations/index.ts +2 -0
- package/src/public/operations/node-ports.ts +1 -39
- package/src/public/operations/proof-receipt-projection.ts +39 -0
- package/src/public/operations/specs/bootstrap.ts +78 -4
- package/src/public/operations/specs/impact-review-preparation.ts +46 -0
- package/src/public/operations/symbol-repair-plan.ts +3 -1
- package/src/public/operations/types.ts +1 -0
- package/src/public/skills/kibi-bootstrap/SKILL.md +47 -11
- package/src/public/skills/kibi-bootstrap/resources/bootstrap.md +6 -1
- package/src/public/skills/kibi-usage/SKILL.md +14 -0
- package/src/public/skills/kibi-usage/resources/operation-access.md +5 -0
- package/src/public/telemetry-acceptance.ts +9 -0
- package/src/traceability/impact-policy.v1.schema.json +48 -0
- package/src/traceability/impact-review.schema.json +365 -0
- package/templates/github/kibi-badge.yml +0 -4
- package/templates/github/kibi-report.yml +0 -4
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { analyzeSourceChanges } from "../plugins/source-change-analysis.js";
|
|
2
|
+
import { evaluateImpactReview, loadBaseImpactPolicy, } from "./impact-evaluator.js";
|
|
3
|
+
/** Authorize lexical coordinate migration only from a captured local staged review.
|
|
4
|
+
* Protected PR hosts must use their target-base evaluator, not this HEAD policy. */
|
|
5
|
+
export function createReviewedDecoratorCoordinateVerifier(snapshot, service, bindings) {
|
|
6
|
+
if (process.env.CI)
|
|
7
|
+
throw new Error("Reviewed partial coordinate migration is unavailable in CI without a protected target-base snapshot");
|
|
8
|
+
const policy = loadBaseImpactPolicy(snapshot);
|
|
9
|
+
let reviewValidation;
|
|
10
|
+
return async (path, analysis) => {
|
|
11
|
+
snapshot.assertUnchanged();
|
|
12
|
+
if (analysis.status !== "partial" ||
|
|
13
|
+
analysis.language !== "python" ||
|
|
14
|
+
analysis.sourceFile !== path ||
|
|
15
|
+
analysis.module.analysisMode !== "parser" ||
|
|
16
|
+
analysis.stamp?.pluginId !== "kibi-plugin-treesitter" ||
|
|
17
|
+
analysis.uncoveredRanges.length === 0 ||
|
|
18
|
+
analysis.providerId !== "kibi-plugin-treesitter.tree-sitter.v2" ||
|
|
19
|
+
analysis.diagnostics.length === 0 ||
|
|
20
|
+
analysis.providerFingerprint === null ||
|
|
21
|
+
!analysis.diagnostics.every((diagnostic) => diagnostic.code === "TREESITTER_DECORATOR_EXPANSION_UNAVAILABLE" &&
|
|
22
|
+
policy.allowedPartial.some((allowed) => allowed.providerId === analysis.providerId &&
|
|
23
|
+
allowed.providerFingerprint ===
|
|
24
|
+
`sha256:${analysis.providerFingerprint}` &&
|
|
25
|
+
allowed.diagnosticCode === diagnostic.code &&
|
|
26
|
+
allowed.limitationClass === "python-decorator-expansion")))
|
|
27
|
+
throw new Error(`Decorator coordinates for ${path} are not allowed by the captured base policy`);
|
|
28
|
+
reviewValidation ??= (async () => {
|
|
29
|
+
const analyses = await analyzeSourceChanges(snapshot.inventory, service);
|
|
30
|
+
// Use the same host normalization as staged check, without changing the
|
|
31
|
+
// original captured inventory used by the generated-byte comparison.
|
|
32
|
+
const evaluatedSnapshot = {
|
|
33
|
+
...snapshot,
|
|
34
|
+
inventory: snapshot.inventory.map((file) => analyses.get(file.path)?.after?.status === "ok"
|
|
35
|
+
? { ...file, analysisDepth: "symbol", disposition: "checked" }
|
|
36
|
+
: { ...file }),
|
|
37
|
+
};
|
|
38
|
+
const result = evaluateImpactReview(evaluatedSnapshot, {
|
|
39
|
+
...bindings,
|
|
40
|
+
analyses,
|
|
41
|
+
});
|
|
42
|
+
if (!result.passed)
|
|
43
|
+
throw new Error(`Reviewed coordinate migration failed: ${result.diagnostics.map((diagnostic) => diagnostic.message).join("; ")}`);
|
|
44
|
+
snapshot.assertUnchanged();
|
|
45
|
+
})();
|
|
46
|
+
await reviewValidation;
|
|
47
|
+
snapshot.assertUnchanged();
|
|
48
|
+
};
|
|
49
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type ExtractionResult } from "../extractors/markdown.js";
|
|
2
|
+
/** Compile authored knowledge from regular blobs of one immutable Git tree. */
|
|
3
|
+
export declare function readSnapshotKnowledge(readGit: (args: readonly string[]) => Buffer, tree: string, readBlobs?: (oids: readonly string[]) => ReadonlyMap<string, Buffer>): ExtractionResult[];
|
|
4
|
+
//# sourceMappingURL=snapshot-knowledge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot-knowledge.d.ts","sourceRoot":"","sources":["../../src/traceability/snapshot-knowledge.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,gBAAgB,EAEtB,MAAM,2BAA2B,CAAC;AAKnC,+EAA+E;AAE/E,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,EAC5C,IAAI,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACnE,gBAAgB,EAAE,CAyGpB"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { load as parseYaml } from "js-yaml";
|
|
2
|
+
import { extractFromManifestString } from "../extractors/manifest.js";
|
|
3
|
+
import { extractFromMarkdownString, } from "../extractors/markdown.js";
|
|
4
|
+
import { convertRecordToRelationship } from "../extractors/relationships.js";
|
|
5
|
+
import { isEntityLanePath } from "../utils/kb-paths.js";
|
|
6
|
+
/** Compile authored knowledge from regular blobs of one immutable Git tree. */
|
|
7
|
+
// implements REQ-014
|
|
8
|
+
export function readSnapshotKnowledge(readGit, tree, readBlobs) {
|
|
9
|
+
const entries = readGit(["ls-tree", "-r", "-z", tree, "--", ".kb"])
|
|
10
|
+
.toString("utf8")
|
|
11
|
+
.split("\0")
|
|
12
|
+
.filter(Boolean);
|
|
13
|
+
const authored = entries.filter((entry) => {
|
|
14
|
+
const file = entry.slice(entry.indexOf("\t") + 1);
|
|
15
|
+
return (file === ".kb/symbols.yaml" ||
|
|
16
|
+
file === ".kb/symbols.yml" ||
|
|
17
|
+
(isEntityLanePath(file) && file.endsWith(".md")) ||
|
|
18
|
+
(file.startsWith(".kb/relationships/") && /\.ya?ml$/.test(file)));
|
|
19
|
+
});
|
|
20
|
+
const blobs = readBlobs?.(authored.map((entry) => entry.slice(0, entry.indexOf("\t")).split(" ")[2] ?? ""));
|
|
21
|
+
const results = [];
|
|
22
|
+
const relationships = [];
|
|
23
|
+
for (const entry of authored) {
|
|
24
|
+
const tab = entry.indexOf("\t");
|
|
25
|
+
const metadata = entry.slice(0, tab).split(" ");
|
|
26
|
+
const file = entry.slice(tab + 1);
|
|
27
|
+
const isManifest = file === ".kb/symbols.yaml" || file === ".kb/symbols.yml";
|
|
28
|
+
const isEntity = isEntityLanePath(file) && file.endsWith(".md");
|
|
29
|
+
const isShard = file.startsWith(".kb/relationships/") && /\.ya?ml$/.test(file);
|
|
30
|
+
if (!isManifest && !isEntity && !isShard)
|
|
31
|
+
continue;
|
|
32
|
+
if (metadata[1] !== "blob" ||
|
|
33
|
+
!["100644", "100755"].includes(metadata[0] ?? ""))
|
|
34
|
+
throw new Error(`Snapshot knowledge must be a regular file: ${file}`);
|
|
35
|
+
const oid = metadata[2];
|
|
36
|
+
if (!oid)
|
|
37
|
+
throw new Error(`Missing snapshot object ID: ${file}`);
|
|
38
|
+
const content = new TextDecoder("utf-8", { fatal: true }).decode(blobs?.get(oid) ?? readGit(["cat-file", "blob", oid]));
|
|
39
|
+
if (isManifest)
|
|
40
|
+
results.push(...extractFromManifestString(content, file));
|
|
41
|
+
else if (isEntity) {
|
|
42
|
+
if (/^---\r?\n/.test(content))
|
|
43
|
+
results.push(extractFromMarkdownString(content, file));
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
const parsed = parseYaml(content);
|
|
47
|
+
if (!parsed || !Array.isArray(parsed.relationships))
|
|
48
|
+
throw new Error(`Invalid snapshot relationship shard: ${file}`);
|
|
49
|
+
for (const row of parsed.relationships) {
|
|
50
|
+
if (!row ||
|
|
51
|
+
typeof row !== "object" ||
|
|
52
|
+
typeof row.type !== "string" ||
|
|
53
|
+
typeof row.from !== "string" ||
|
|
54
|
+
typeof row.to !== "string")
|
|
55
|
+
throw new Error(`Invalid snapshot relationship in ${file}`);
|
|
56
|
+
relationships.push(row);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const byId = new Map();
|
|
61
|
+
const duplicates = new Map();
|
|
62
|
+
for (const result of results) {
|
|
63
|
+
const previous = byId.get(result.entity.id);
|
|
64
|
+
if (previous) {
|
|
65
|
+
const declarations = duplicates.get(result.entity.id) ?? [previous];
|
|
66
|
+
declarations.push(result);
|
|
67
|
+
duplicates.set(result.entity.id, declarations);
|
|
68
|
+
}
|
|
69
|
+
else
|
|
70
|
+
byId.set(result.entity.id, result);
|
|
71
|
+
}
|
|
72
|
+
if (duplicates.size > 0)
|
|
73
|
+
throw new Error(`Duplicate snapshot entities: ${JSON.stringify([...duplicates].map(([id, declarations]) => ({
|
|
74
|
+
id,
|
|
75
|
+
declarations: declarations.map((row) => ({
|
|
76
|
+
title: row.entity.title,
|
|
77
|
+
status: row.entity.status,
|
|
78
|
+
source: row.entity.source,
|
|
79
|
+
sourceFile: row.sourceFile,
|
|
80
|
+
})),
|
|
81
|
+
})))}`);
|
|
82
|
+
for (const row of relationships) {
|
|
83
|
+
const relation = convertRecordToRelationship(row);
|
|
84
|
+
if (!relation)
|
|
85
|
+
continue;
|
|
86
|
+
const owner = byId.get(relation.from);
|
|
87
|
+
if (!owner || !byId.has(relation.to))
|
|
88
|
+
throw new Error(`Snapshot relationship has a missing endpoint: ${relation.from} -> ${relation.to}`);
|
|
89
|
+
owner.relationships.push(relation);
|
|
90
|
+
}
|
|
91
|
+
for (const result of results) {
|
|
92
|
+
for (const relation of result.relationships) {
|
|
93
|
+
if (!byId.has(relation.from) || !byId.has(relation.to))
|
|
94
|
+
throw new Error(`Snapshot relationship has a missing endpoint: ${relation.from} -> ${relation.to}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return results;
|
|
98
|
+
}
|
|
@@ -10,6 +10,24 @@ export interface StagedFileCoverageRecord {
|
|
|
10
10
|
requirementIds: string[];
|
|
11
11
|
evidencePaths: string[];
|
|
12
12
|
providerId: string | null;
|
|
13
|
+
sourceAnalysis?: {
|
|
14
|
+
before: {
|
|
15
|
+
status: string;
|
|
16
|
+
language: string;
|
|
17
|
+
symbolCount: number;
|
|
18
|
+
providerId: string | null;
|
|
19
|
+
inputFingerprint: string;
|
|
20
|
+
providerFingerprint: string | null;
|
|
21
|
+
} | null;
|
|
22
|
+
after: {
|
|
23
|
+
status: string;
|
|
24
|
+
language: string;
|
|
25
|
+
symbolCount: number;
|
|
26
|
+
providerId: string | null;
|
|
27
|
+
inputFingerprint: string;
|
|
28
|
+
providerFingerprint: string | null;
|
|
29
|
+
} | null;
|
|
30
|
+
};
|
|
13
31
|
}
|
|
14
32
|
export interface StagedFileCoverageDiagnostic {
|
|
15
33
|
id: "staged_file_ownership_missing" | "staged_file_impact_review_needed";
|
|
@@ -23,6 +41,11 @@ export interface StagedFileCoverageDiagnostic {
|
|
|
23
41
|
}
|
|
24
42
|
export interface StagedFileCoverageResult {
|
|
25
43
|
version: typeof STAGED_FILE_COVERAGE_RESULT_VERSION;
|
|
44
|
+
snapshot?: {
|
|
45
|
+
baseTree: string;
|
|
46
|
+
headTree: string;
|
|
47
|
+
headCommit: string | null;
|
|
48
|
+
};
|
|
26
49
|
files: StagedFileCoverageRecord[];
|
|
27
50
|
diagnostics: StagedFileCoverageDiagnostic[];
|
|
28
51
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"staged-file-coverage.d.ts","sourceRoot":"","sources":["../../src/traceability/staged-file-coverage.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,eAAO,MAAM,mCAAmC,EAC9C,8BAAuC,CAAC;AAE1C,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC7B,aAAa,EAAE,UAAU,CAAC,eAAe,CAAC,CAAC;IAC3C,WAAW,EAAE,UAAU,CAAC,aAAa,CAAC,CAAC;IACvC,MAAM,CAAC,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC;IAClC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"staged-file-coverage.d.ts","sourceRoot":"","sources":["../../src/traceability/staged-file-coverage.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,eAAO,MAAM,mCAAmC,EAC9C,8BAAuC,CAAC;AAE1C,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC7B,aAAa,EAAE,UAAU,CAAC,eAAe,CAAC,CAAC;IAC3C,WAAW,EAAE,UAAU,CAAC,aAAa,CAAC,CAAC;IACvC,MAAM,CAAC,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC;IAClC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,cAAc,CAAC,EAAE;QACf,MAAM,EAAE;YACN,MAAM,EAAE,MAAM,CAAC;YACf,QAAQ,EAAE,MAAM,CAAC;YACjB,WAAW,EAAE,MAAM,CAAC;YACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;YAC1B,gBAAgB,EAAE,MAAM,CAAC;YACzB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;SACpC,GAAG,IAAI,CAAC;QACT,KAAK,EAAE;YACL,MAAM,EAAE,MAAM,CAAC;YACf,QAAQ,EAAE,MAAM,CAAC;YACjB,WAAW,EAAE,MAAM,CAAC;YACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;YAC1B,gBAAgB,EAAE,MAAM,CAAC;YACzB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;SACpC,GAAG,IAAI,CAAC;KACV,CAAC;CACH;AAED,MAAM,WAAW,4BAA4B;IAC3C,EAAE,EAAE,+BAA+B,GAAG,kCAAkC,CAAC;IACzE,QAAQ,EAAE,SAAS,CAAC;IACpB,QAAQ,EAAE,KAAK,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,OAAO,mCAAmC,CAAC;IACpD,QAAQ,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAC7E,KAAK,EAAE,wBAAwB,EAAE,CAAC;IAClC,WAAW,EAAE,4BAA4B,EAAE,CAAC;CAC7C;AAGD,KAAK,SAAS,GAAG,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,MAAM,CAAC;AA+OrD,2FAA2F;AAC3F,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,SAAS,UAAU,EAAE,EAChC,MAAM,GAAE,SAA4B,GACnC,wBAAwB,CA0G1B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"staged-impact-contract.d.ts","sourceRoot":"","sources":["../../src/traceability/staged-impact-contract.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"staged-impact-contract.d.ts","sourceRoot":"","sources":["../../src/traceability/staged-impact-contract.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,0BAA0B,+GAI7B,CAAC;AAEX,MAAM,MAAM,sBAAsB,GAChC,CAAC,OAAO,0BAA0B,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9C,MAAM,MAAM,sBAAsB,GAC9B,iBAAiB,GACjB,kBAAkB,GAClB,mBAAmB,CAAC;AAExB,MAAM,WAAW,4BAA4B;IAC3C,EAAE,EAAE,sBAAsB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,+BAA+B,EAAE,OAAO,CAAC;IACzC,sBAAsB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,4BAA4B;IAC3C,kBAAkB,EAAE,OAAO,CAAC;IAC5B,QAAQ,EAAE,wBAAwB,CAAC;CACpC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAC1C,sBAAsB,EACtB,4BAA4B,CA6B7B,CAAC;AAEF,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,uBAAuB,GAC7B,sBAAsB,GAAG,IAAI,CAsB/B;AAED,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,GACX,wBAAwB,CAS1B;AAED,wBAAgB,gCAAgC,CAC9C,KAAK,EAAE,4BAA4B,GAClC,OAAO,CAMT;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,uBAAuB,GAAG,OAAO,CA8B5E;AAED,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEvE"}
|
|
@@ -1,14 +1,5 @@
|
|
|
1
|
+
import { isTsJsSourcePath } from "../plugins/source-classification.js";
|
|
1
2
|
import { isEntityLanePath, isSymbolsManifestPath } from "../utils/kb-paths.js";
|
|
2
|
-
const SUPPORTED_BEHAVIOR_SOURCE_EXTENSIONS = new Set([
|
|
3
|
-
".ts",
|
|
4
|
-
".tsx",
|
|
5
|
-
".js",
|
|
6
|
-
".jsx",
|
|
7
|
-
".mts",
|
|
8
|
-
".cts",
|
|
9
|
-
".mjs",
|
|
10
|
-
".cjs",
|
|
11
|
-
]);
|
|
12
3
|
export const KIBI_IMPACT_DIAGNOSTIC_IDS = [
|
|
13
4
|
"kibi_impact_evidence_missing",
|
|
14
5
|
"symbols_manifest_stale",
|
|
@@ -118,12 +109,7 @@ export function isBehaviorSourceEdit(input) {
|
|
|
118
109
|
return true;
|
|
119
110
|
}
|
|
120
111
|
export function isSupportedBehaviorSourcePath(filePath) {
|
|
121
|
-
|
|
122
|
-
if (filePath.endsWith(extension)) {
|
|
123
|
-
return true;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
return false;
|
|
112
|
+
return isTsJsSourcePath(filePath);
|
|
127
113
|
}
|
|
128
114
|
function isEntityEvidenceMarkdown(filePath) {
|
|
129
115
|
if (!filePath.endsWith(".md")) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SourceAnalysisResult } from "kibi-plugin-sdk";
|
|
1
2
|
import { type ParsedCoordinateArtifact } from "../extractors/symbol-coordinates.js";
|
|
2
3
|
import type { KibiImpactSymbolsManifestFileDetail } from "./evidence-model.js";
|
|
3
4
|
import type { StagedFile } from "./git-staged.js";
|
|
@@ -29,9 +30,12 @@ export declare function assessStagedSymbolsManifest(options: {
|
|
|
29
30
|
symbolsManifestPath: string;
|
|
30
31
|
sourceFiles: StagedFile[];
|
|
31
32
|
stagedFiles: StagedFile[];
|
|
33
|
+
readBaseFile?: (filePath: string) => string | null;
|
|
34
|
+
analyzeSource?: (filePath: string, content: string) => SourceAnalysisResult;
|
|
32
35
|
}): StagedSymbolsManifestAssessment;
|
|
33
36
|
export declare function collectStagedAuthoredSymbolsManifestEvidence(options: {
|
|
34
37
|
sourceFiles: StagedFile[];
|
|
35
38
|
stagedFiles: StagedFile[];
|
|
39
|
+
readBaseFile?: (filePath: string) => string | null;
|
|
36
40
|
}): StagedAuthoredSymbolsManifestEvidence;
|
|
37
41
|
//# sourceMappingURL=staged-symbols-manifest.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"staged-symbols-manifest.d.ts","sourceRoot":"","sources":["../../src/traceability/staged-symbols-manifest.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"staged-symbols-manifest.d.ts","sourceRoot":"","sources":["../../src/traceability/staged-symbols-manifest.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,oBAAoB,EAErB,MAAM,iBAAiB,CAAC;AAKzB,OAAO,EACL,KAAK,wBAAwB,EAG9B,MAAM,qCAAqC,CAAC;AAI7C,OAAO,KAAK,EAAE,mCAAmC,EAAE,MAAM,qBAAqB,CAAC;AAC/E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AA0ClD,MAAM,WAAW,+BAA+B;IAC9C,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,cAAc,CAAC;IACtD,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,WAAW,CAAC,EAAE,mCAAmC,EAAE,CAAC;CACrD;AAED,MAAM,WAAW,qCAAqC;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,KAAK,CAAC;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IAC5D,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B;AA6ED,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,MAAM,wBAAwB,GACpC,wBAAwB,GAAG,IAAI,CAOjC;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE;IAC/C,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,GAAG,MAAM,GAAG,IAAI,CAMhB;AAqTD,wBAAgB,2BAA2B,CAAC,OAAO,EAAE;IACnD,mBAAmB,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACnD,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,oBAAoB,CAAC;CAC7E,GAAG,+BAA+B,CAoLlC;AAED,wBAAgB,4CAA4C,CAAC,OAAO,EAAE;IACpE,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACpD,GAAG,qCAAqC,CAqExC"}
|
|
@@ -215,11 +215,18 @@ function getChangedAuthoredEntityIds(headSymbols, stagedSymbols) {
|
|
|
215
215
|
});
|
|
216
216
|
return uniqueSorted(changedIds);
|
|
217
217
|
}
|
|
218
|
-
function normalizeExpectedSymbolsForStagedFile(stagedFile) {
|
|
219
|
-
const analysis = analyzeSourceText(stagedFile.path, stagedFile.content ?? "");
|
|
218
|
+
function normalizeExpectedSymbolsForStagedFile(stagedFile, analyze, authoredTitles = new Set()) {
|
|
219
|
+
const analysis = (analyze ?? analyzeSourceText)(stagedFile.path, stagedFile.content ?? "");
|
|
220
220
|
return analysis.symbols
|
|
221
221
|
.map((symbol) => ({
|
|
222
|
-
title:
|
|
222
|
+
title: (() => {
|
|
223
|
+
const qualified = symbol.qualifiedName;
|
|
224
|
+
if (!qualified ||
|
|
225
|
+
(authoredTitles.has(symbol.name) &&
|
|
226
|
+
analysis.symbols.filter((candidate) => candidate.name === symbol.name).length === 1))
|
|
227
|
+
return symbol.name;
|
|
228
|
+
return qualified;
|
|
229
|
+
})(),
|
|
223
230
|
sourceFile: stagedFile.path,
|
|
224
231
|
sourceLine: symbol.startLine,
|
|
225
232
|
sourceColumn: symbol.startColumn,
|
|
@@ -290,7 +297,9 @@ export function assessStagedSymbolsManifest(options) {
|
|
|
290
297
|
// assess several commits in the same checkout; a process-global cache would
|
|
291
298
|
// otherwise reuse content from the previous HEAD.
|
|
292
299
|
const headFileContentCache = new Map();
|
|
293
|
-
const readAssessmentHeadFileContent = (filePath) =>
|
|
300
|
+
const readAssessmentHeadFileContent = (filePath) => options.readBaseFile
|
|
301
|
+
? options.readBaseFile(filePath)
|
|
302
|
+
: readHeadFileContent(filePath, headFileContentCache);
|
|
294
303
|
const headManifestRecords = parseManifestRecords(readAssessmentHeadFileContent(paths.symbolsPath), paths.symbolsPath);
|
|
295
304
|
const headCoordinateArtifact = parseCoordinateArtifact(readAssessmentHeadFileContent(paths.coordinatesPath));
|
|
296
305
|
const { stagedCoordinatesFile, stagedCoordinateArtifact, stagedManifestRecords, } = getEffectiveManifestRecords({
|
|
@@ -342,7 +351,7 @@ export function assessStagedSymbolsManifest(options) {
|
|
|
342
351
|
const coarseTitles = new Set([...recordsByTitle.entries()]
|
|
343
352
|
.filter(([, records]) => records.every(isDocumentedCoarseRecord))
|
|
344
353
|
.map(([title]) => title));
|
|
345
|
-
const expectedSymbols = normalizeExpectedSymbolsForStagedFile(sourceFile).filter((symbol) => !coarseTitles.has(symbol.title));
|
|
354
|
+
const expectedSymbols = normalizeExpectedSymbolsForStagedFile(sourceFile, options.analyzeSource, new Set(recordsByTitle.keys())).filter((symbol) => !coarseTitles.has(symbol.title));
|
|
346
355
|
const baselineSymbols = normalizeManifestSymbolsForSourceFile(baselineMergedRecords, sourceFile.path);
|
|
347
356
|
if (signaturesEqual(expectedSymbols, baselineSymbols)) {
|
|
348
357
|
continue;
|
|
@@ -406,7 +415,9 @@ export function collectStagedAuthoredSymbolsManifestEvidence(options) {
|
|
|
406
415
|
if (!stagedManifestFile) {
|
|
407
416
|
return { path: paths.symbolsPath, entries: [], changedEntityIds: [] };
|
|
408
417
|
}
|
|
409
|
-
const headManifestRecords = parseManifestRecords(
|
|
418
|
+
const headManifestRecords = parseManifestRecords(options.readBaseFile
|
|
419
|
+
? options.readBaseFile(paths.symbolsPath)
|
|
420
|
+
: readHeadFileContent(paths.symbolsPath), paths.symbolsPath) ?? [];
|
|
410
421
|
const stagedManifestRecords = parseManifestRecords(stagedManifestFile.content, paths.symbolsPath);
|
|
411
422
|
if (stagedManifestRecords === null) {
|
|
412
423
|
return { path: paths.symbolsPath, entries: [], changedEntityIds: [] };
|
|
@@ -4,6 +4,7 @@ import { type SymbolKind, type SymbolRole } from "../public/symbol-granularity.j
|
|
|
4
4
|
import type { HunkRange, StagedFile } from "./git-staged.js";
|
|
5
5
|
type SourceAnalysisResult = SdkSourceAnalysisResult & {
|
|
6
6
|
providerId?: string | null;
|
|
7
|
+
status?: "ok" | "partial" | "unsupported" | "failed";
|
|
7
8
|
};
|
|
8
9
|
type TraceabilityRelationship = {
|
|
9
10
|
type: string;
|
|
@@ -38,11 +39,8 @@ export type ExtractSymbolsOptions = Readonly<{
|
|
|
38
39
|
}>;
|
|
39
40
|
export declare function extractSymbolsFromStagedFile(stagedFile: StagedFile, manifestLookup?: ManifestLookup, options?: ExtractSymbolsOptions): ExtractedSymbol[];
|
|
40
41
|
/**
|
|
41
|
-
* Async
|
|
42
|
-
*
|
|
43
|
-
* replace/augment/shadow (e.g. symbol repair). Maintenance paths (`check`,
|
|
44
|
-
* impact, sync, status, proof) must omit `registry` so external extractors
|
|
45
|
-
* never participate.
|
|
42
|
+
* Async extraction from supplied snapshot bytes. Maintenance callers inject the
|
|
43
|
+
* shared, host-approved v2 analysis; legacy direct callers retain v1 behavior.
|
|
46
44
|
*/
|
|
47
45
|
export declare function extractSymbolsFromStagedFileAsync(stagedFile: StagedFile, manifestLookup: ManifestLookup | undefined, options: ExtractSymbolsOptions & Readonly<{
|
|
48
46
|
registry?: import("../plugins/registry.js").CapabilityRegistry;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"symbol-extract.d.ts","sourceRoot":"","sources":["../../src/traceability/symbol-extract.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,IAAI,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAEvF,OAAO,EAEL,oBAAoB,EACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,KAAK,UAAU,EACf,KAAK,UAAU,EAEhB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7D,KAAK,oBAAoB,GAAG,uBAAuB,GAAG;IACpD,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"symbol-extract.d.ts","sourceRoot":"","sources":["../../src/traceability/symbol-extract.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,IAAI,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAEvF,OAAO,EAEL,oBAAoB,EACrB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,KAAK,UAAU,EACf,KAAK,UAAU,EAEhB,MAAM,iCAAiC,CAAC;AACzC,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7D,KAAK,oBAAoB,GAAG,uBAAuB,GAAG;IACpD,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,CAAC,EAAE,IAAI,GAAG,SAAS,GAAG,aAAa,GAAG,QAAQ,CAAC;CACtD,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAU7D,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAC5C;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,CAAC,EAAE,wBAAwB,EAAE,CAAC;CAC5C;AAED,MAAM,MAAM,cAAc,GAAG,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC;AAE9D,wBAAgB,+BAA+B,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAG5E;AA0ND,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C;;;OAGG;IACH,WAAW,CAAC,EAAE,CACZ,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,KACZ,oBAAoB,GAAG,IAAI,GAAG,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAAC,CAAC;CACzE,CAAC,CAAC;AAWH,wBAAgB,4BAA4B,CAE1C,UAAU,EAAE,UAAU,EACtB,cAAc,CAAC,EAAE,cAAc,EAC/B,OAAO,CAAC,EAAE,qBAAqB,GAC9B,eAAe,EAAE,CAkCnB;AAED;;;GAGG;AAEH,wBAAsB,iCAAiC,CACrD,UAAU,EAAE,UAAU,EACtB,cAAc,EAAE,cAAc,GAAG,SAAS,EAC1C,OAAO,EAAE,qBAAqB,GAC5B,QAAQ,CAAC;IACP,QAAQ,CAAC,EAAE,OAAO,wBAAwB,EAAE,kBAAkB,CAAC;CAChE,CAAC,GACH,OAAO,CAAC,eAAe,EAAE,CAAC,CAuB5B;AA0DD,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
|
|
@@ -51,7 +51,8 @@ function resolveSymbolTraceability(filePath, name, manifestLookup) {
|
|
|
51
51
|
}
|
|
52
52
|
const candidateManifestPaths = getCandidateManifestPaths(filePath);
|
|
53
53
|
if (manifestLookup &&
|
|
54
|
-
|
|
54
|
+
(manifestLookup.has(createManifestLookupSentinelKey(".kb/symbols.yaml")) ||
|
|
55
|
+
candidateManifestPaths.some((manifestPath) => manifestLookup.has(createManifestLookupSentinelKey(manifestPath))))) {
|
|
55
56
|
return { id: createHashFallbackId(filePath, name) };
|
|
56
57
|
}
|
|
57
58
|
for (const manifestPath of candidateManifestPaths) {
|
|
@@ -193,52 +194,52 @@ stagedFile, manifestLookup, options) {
|
|
|
193
194
|
return symbolsFromAnalysis(stagedFile, cached.result, manifestLookup);
|
|
194
195
|
}
|
|
195
196
|
/**
|
|
196
|
-
* Async
|
|
197
|
-
*
|
|
198
|
-
* replace/augment/shadow (e.g. symbol repair). Maintenance paths (`check`,
|
|
199
|
-
* impact, sync, status, proof) must omit `registry` so external extractors
|
|
200
|
-
* never participate.
|
|
197
|
+
* Async extraction from supplied snapshot bytes. Maintenance callers inject the
|
|
198
|
+
* shared, host-approved v2 analysis; legacy direct callers retain v1 behavior.
|
|
201
199
|
*/
|
|
202
200
|
// implements REQ-capability-plugin-activation-disclosure-v1
|
|
203
201
|
export async function extractSymbolsFromStagedFileAsync(stagedFile, manifestLookup, options) {
|
|
204
202
|
const content = stagedFile.content ?? "";
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
let
|
|
208
|
-
if (
|
|
209
|
-
|
|
210
|
-
let analysis = null;
|
|
211
|
-
if (options.analyzeText) {
|
|
212
|
-
analysis = await options.analyzeText(stagedFile.path, content);
|
|
213
|
-
}
|
|
214
|
-
else if (options.registry) {
|
|
215
|
-
const { createSourceAnalysisService } = await import("../plugins/source-analysis-service.js");
|
|
216
|
-
analysis = await createSourceAnalysisService({
|
|
217
|
-
registry: options.registry,
|
|
218
|
-
}).analyzeText(stagedFile.path, content);
|
|
219
|
-
}
|
|
220
|
-
else {
|
|
221
|
-
analysis = analyzeWithBuiltinFallback(stagedFile.path, content);
|
|
222
|
-
}
|
|
223
|
-
cached = { result: analysis, ts: now };
|
|
224
|
-
analysisCache.set(sha, cached);
|
|
225
|
-
}
|
|
226
|
-
catch {
|
|
227
|
-
cached = { result: null, ts: now };
|
|
228
|
-
analysisCache.set(sha, cached);
|
|
229
|
-
}
|
|
203
|
+
// Do not cache by a generic "custom" provider key: provider/query versions
|
|
204
|
+
// and snapshot contexts differ. The host owns any structural-analysis cache.
|
|
205
|
+
let analysis;
|
|
206
|
+
if (options.analyzeText) {
|
|
207
|
+
analysis = await options.analyzeText(stagedFile.path, content);
|
|
230
208
|
}
|
|
231
|
-
|
|
209
|
+
else if (options.registry) {
|
|
210
|
+
const { createSourceAnalysisService } = await import("../plugins/source-analysis-service.js");
|
|
211
|
+
analysis = await createSourceAnalysisService({
|
|
212
|
+
registry: options.registry,
|
|
213
|
+
}).analyzeText(stagedFile.path, content);
|
|
214
|
+
}
|
|
215
|
+
else {
|
|
216
|
+
analysis = analyzeWithBuiltinFallback(stagedFile.path, content);
|
|
217
|
+
}
|
|
218
|
+
if (analysis?.status === "failed" || analysis?.status === "partial") {
|
|
219
|
+
throw new Error(`Source analysis ${analysis.status} for ${stagedFile.path}; complete symbol validation is unavailable`);
|
|
220
|
+
}
|
|
221
|
+
return symbolsFromAnalysis(stagedFile, analysis, manifestLookup);
|
|
232
222
|
}
|
|
233
223
|
function symbolsFromAnalysis(stagedFile, analysis, manifestLookup) {
|
|
234
224
|
if (!analysis)
|
|
235
225
|
return [];
|
|
226
|
+
if (analysis.status !== undefined) {
|
|
227
|
+
const locators = new Set();
|
|
228
|
+
for (const symbol of analysis.symbols) {
|
|
229
|
+
const locator = symbol.qualifiedName ?? symbol.name;
|
|
230
|
+
if (locators.has(locator))
|
|
231
|
+
throw new Error(`Ambiguous declaration locator '${locator}' in ${stagedFile.path}; authored identity cannot be assigned`);
|
|
232
|
+
locators.add(locator);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
236
235
|
const results = [];
|
|
237
236
|
for (const symbol of analysis.symbols) {
|
|
238
237
|
try {
|
|
239
|
-
results.push(buildSymbolResult(stagedFile, symbol.
|
|
238
|
+
results.push(buildSymbolResult(stagedFile, sourceSymbolLocator(symbol, analysis.symbols, stagedFile.path, manifestLookup), symbol.kind, { startLine: symbol.startLine, endLine: symbol.endLine }, parseReqDirectives(symbol.directiveText ?? ""), manifestLookup));
|
|
240
239
|
}
|
|
241
|
-
catch {
|
|
240
|
+
catch (error) {
|
|
241
|
+
if (analysis.status !== undefined)
|
|
242
|
+
throw error;
|
|
242
243
|
void stagedFile.path;
|
|
243
244
|
}
|
|
244
245
|
}
|
|
@@ -259,3 +260,17 @@ function intersectingHunks(startLine, endLine, hunks) {
|
|
|
259
260
|
}
|
|
260
261
|
return out;
|
|
261
262
|
}
|
|
263
|
+
// implements REQ-008
|
|
264
|
+
function sourceSymbolLocator(symbol, symbols, filePath, lookup) {
|
|
265
|
+
const qualified = symbol.qualifiedName;
|
|
266
|
+
if (!qualified || qualified === symbol.name)
|
|
267
|
+
return symbol.name;
|
|
268
|
+
if (lookup?.has(`${filePath}:${qualified}`))
|
|
269
|
+
return qualified;
|
|
270
|
+
// Preserve an authored legacy unqualified locator only when unambiguous.
|
|
271
|
+
if (symbols.filter((candidate) => candidate.name === symbol.name).length ===
|
|
272
|
+
1 &&
|
|
273
|
+
lookup?.has(`${filePath}:${symbol.name}`))
|
|
274
|
+
return symbol.name;
|
|
275
|
+
return qualified;
|
|
276
|
+
}
|
|
@@ -24,7 +24,7 @@ export declare function _setPrologFactory(factory: (opts: {
|
|
|
24
24
|
declare function consultOverlay(ctx: TempKbContext): Promise<void>;
|
|
25
25
|
export { consultOverlay };
|
|
26
26
|
export declare function projectStagedEntities(prolog: PrologProcess, results: ExtractionResult[]): Promise<void>;
|
|
27
|
-
export declare function createTempKb(baseKbPath
|
|
27
|
+
export declare function createTempKb(baseKbPath?: string): Promise<TempKbContext>;
|
|
28
28
|
export declare function createOverlayFacts(symbols: ExtractedSymbol[]): string;
|
|
29
29
|
export declare function cleanupTempKb(tempDir: string): Promise<void>;
|
|
30
30
|
//# sourceMappingURL=temp-kb.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"temp-kb.d.ts","sourceRoot":"","sources":["../../src/traceability/temp-kb.ts"],"names":[],"mappings":"AAMA,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,OAAO,CAET;AACD,OAAO,KAAK,EAGV,gBAAgB,EACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;CACvB;AAMD;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CASvC;AAQD;;;GAGG;AACH,wBAAgB,iBAAiB,CAE/B,OAAO,EAAE,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,KAAK,CAAA;CAAE,KAAK,aAAa,GACpE,IAAI,CAEN;AA4QD,iBAAe,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB/D;AAED,OAAO,EAAE,cAAc,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"temp-kb.d.ts","sourceRoot":"","sources":["../../src/traceability/temp-kb.ts"],"names":[],"mappings":"AAMA,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GACZ,OAAO,CAET;AACD,OAAO,KAAK,EAGV,gBAAgB,EACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,aAAa,CAAC;CACvB;AAMD;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CASvC;AAQD;;;GAGG;AACH,wBAAgB,iBAAiB,CAE/B,OAAO,EAAE,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,KAAK,CAAA;CAAE,KAAK,aAAa,GACpE,IAAI,CAEN;AA4QD,iBAAe,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB/D;AAED,OAAO,EAAE,cAAc,EAAE,CAAC;AAe1B,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,gBAAgB,EAAE,GAC1B,OAAO,CAAC,IAAI,CAAC,CA4Df;AAED,wBAAsB,YAAY,CAChC,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,aAAa,CAAC,CA+CxB;AAGD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,MAAM,CAkBrE;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BlE"}
|
|
@@ -266,29 +266,62 @@ async function consultOverlay(ctx) {
|
|
|
266
266
|
}
|
|
267
267
|
}
|
|
268
268
|
export { consultOverlay };
|
|
269
|
+
const PROJECTION_BATCH_SIZE = 128;
|
|
270
|
+
// implements REQ-014
|
|
271
|
+
function contextualProjectionGoal(goal, context) {
|
|
272
|
+
const label = toPrologString(context);
|
|
273
|
+
// A failed goal must abort the transaction just like an exception. Keep the
|
|
274
|
+
// individual record in the error even when it belongs to a larger batch.
|
|
275
|
+
// Use the existing structured validation-error transport; unrecognized error
|
|
276
|
+
// terms can lose their record context during generic error classification.
|
|
277
|
+
return `catch((${goal} -> true ; throw(staged_goal_failed)), ProjectionError, (message_to_string(ProjectionError, ProjectionDetail), format(atom(ProjectionMessage), '~s: ~s', [${label}, ProjectionDetail]), throw(error(validation_error(ProjectionMessage), context(projectStagedEntities, ${label})))))`;
|
|
278
|
+
}
|
|
269
279
|
// implements REQ-014
|
|
270
280
|
export async function projectStagedEntities(prolog, results) {
|
|
271
|
-
for (
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
281
|
+
for (let offset = 0; offset < results.length; offset += PROJECTION_BATCH_SIZE) {
|
|
282
|
+
const batch = results.slice(offset, offset + PROJECTION_BATCH_SIZE);
|
|
283
|
+
const goals = batch.flatMap(({ entity, sourceFile }) => [
|
|
284
|
+
// Upserts preserve relationships, so replace them with snapshot edges.
|
|
285
|
+
contextualProjectionGoal(`kb_retract_entity_relationships(${toPrologAtom(entity.id)})`, `retract staged relationships for entity ${entity.id}`),
|
|
286
|
+
contextualProjectionGoal(buildEntityAssertionGoal(entity, sourceFile), `assert staged entity ${entity.id}`),
|
|
287
|
+
]);
|
|
288
|
+
// query(array) wraps the batch in an RDF transaction and saves once.
|
|
289
|
+
const result = await prolog.query(goals);
|
|
290
|
+
if (!result.success) {
|
|
291
|
+
const label = batch.map(({ entity }) => entity.id).join(", ");
|
|
292
|
+
throw new Error(`Failed to assert staged entity ${label}: ${result.error || "unknown error"}`);
|
|
278
293
|
}
|
|
279
294
|
}
|
|
295
|
+
// Finish every entity before adding any relationships, including endpoints
|
|
296
|
+
// in later batches. Keep only one bounded batch of relationship goals.
|
|
297
|
+
let relationshipGoals = [];
|
|
298
|
+
let relationshipLabels = [];
|
|
299
|
+
// implements REQ-014
|
|
300
|
+
const flushRelationships = async () => {
|
|
301
|
+
if (relationshipGoals.length === 0)
|
|
302
|
+
return;
|
|
303
|
+
const result = await prolog.query(relationshipGoals);
|
|
304
|
+
if (!result.success) {
|
|
305
|
+
const label = relationshipLabels.join(", ");
|
|
306
|
+
throw new Error(`Failed to assert staged relationship ${label}: ${result.error || "unknown error"}`);
|
|
307
|
+
}
|
|
308
|
+
relationshipGoals = [];
|
|
309
|
+
relationshipLabels = [];
|
|
310
|
+
};
|
|
280
311
|
for (const { relationships } of results) {
|
|
281
312
|
for (const relationship of relationships) {
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
313
|
+
const label = `${relationship.type} ${relationship.from} -> ${relationship.to}`;
|
|
314
|
+
relationshipLabels.push(label);
|
|
315
|
+
relationshipGoals.push(contextualProjectionGoal(buildRelationshipAssertionGoal(relationship), `assert staged relationship ${label}`));
|
|
316
|
+
if (relationshipGoals.length === PROJECTION_BATCH_SIZE)
|
|
317
|
+
await flushRelationships();
|
|
286
318
|
}
|
|
287
319
|
}
|
|
320
|
+
await flushRelationships();
|
|
288
321
|
}
|
|
289
322
|
export async function createTempKb(baseKbPath) {
|
|
290
323
|
// implements REQ-014
|
|
291
|
-
if (!existsSync(baseKbPath)) {
|
|
324
|
+
if (baseKbPath !== undefined && !existsSync(baseKbPath)) {
|
|
292
325
|
throw new Error(`Base KB path does not exist: ${baseKbPath}`);
|
|
293
326
|
}
|
|
294
327
|
// Use crypto.randomUUID() for uniqueness across concurrent calls
|
|
@@ -298,7 +331,10 @@ export async function createTempKb(baseKbPath) {
|
|
|
298
331
|
trace(`creating temp KB directory ${tempDir}`);
|
|
299
332
|
await mkdir(tempDir, { recursive: true });
|
|
300
333
|
trace(`copying base KB ${baseKbPath} -> ${kbPath}`);
|
|
301
|
-
|
|
334
|
+
if (baseKbPath !== undefined)
|
|
335
|
+
await cp(baseKbPath, kbPath, { recursive: true });
|
|
336
|
+
else
|
|
337
|
+
await mkdir(kbPath, { recursive: true });
|
|
302
338
|
await writeFile(overlayPath, "", "utf8");
|
|
303
339
|
const prolog = _createProlog({ timeout: 120000, oneShot: false });
|
|
304
340
|
await prolog.start();
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type TrustedPullRequestSnapshot = Readonly<{
|
|
2
|
+
repository: string;
|
|
3
|
+
targetRef: string;
|
|
4
|
+
targetCommit: string;
|
|
5
|
+
targetTree: string;
|
|
6
|
+
headCommit: string;
|
|
7
|
+
headTree: string;
|
|
8
|
+
mergeBaseCommit: string;
|
|
9
|
+
mergeBaseTree: string;
|
|
10
|
+
}>;
|
|
11
|
+
/** Verify a GitHub pull_request_target envelope against the protected checkout. */
|
|
12
|
+
export declare function resolveTrustedPullRequestSnapshot(workspaceRoot: string, environment?: NodeJS.ProcessEnv): TrustedPullRequestSnapshot;
|
|
13
|
+
//# sourceMappingURL=trusted-pr-event.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trusted-pr-event.d.ts","sourceRoot":"","sources":["../../src/traceability/trusted-pr-event.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAAC;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC,CAAC;AAkDH,mFAAmF;AACnF,wBAAgB,iCAAiC,CAC/C,aAAa,EAAE,MAAM,EACrB,WAAW,GAAE,MAAM,CAAC,UAAwB,GAC3C,0BAA0B,CAqF5B"}
|