sdl-mcp 0.11.11 → 0.11.13
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/.tsbuildinfo +1 -1
- package/dist/cli/commands/serve.d.ts.map +1 -1
- package/dist/cli/commands/serve.js +233 -217
- package/dist/cli/commands/serve.js.map +1 -1
- package/dist/db/ladybug.d.ts +6 -0
- package/dist/db/ladybug.d.ts.map +1 -1
- package/dist/db/ladybug.js +32 -0
- package/dist/db/ladybug.js.map +1 -1
- package/dist/indexer/indexer-pass1.d.ts.map +1 -1
- package/dist/indexer/indexer-pass1.js +3 -1
- package/dist/indexer/indexer-pass1.js.map +1 -1
- package/dist/indexer/indexer.d.ts +1 -0
- package/dist/indexer/indexer.d.ts.map +1 -1
- package/dist/indexer/indexer.js +643 -674
- package/dist/indexer/indexer.js.map +1 -1
- package/dist/indexer/language-packs.js +16 -1
- package/dist/indexer/language-packs.js.map +1 -1
- package/dist/indexer/provider-first/materializer.d.ts +2 -0
- package/dist/indexer/provider-first/materializer.d.ts.map +1 -1
- package/dist/indexer/provider-first/materializer.js +82 -0
- package/dist/indexer/provider-first/materializer.js.map +1 -1
- package/dist/indexer/provider-first/source-call-proof.d.ts.map +1 -1
- package/dist/indexer/provider-first/source-call-proof.js +25 -0
- package/dist/indexer/provider-first/source-call-proof.js.map +1 -1
- package/dist/main.js +62 -52
- package/dist/main.js.map +1 -1
- package/dist/startup/process-handlers.d.ts.map +1 -1
- package/dist/startup/process-handlers.js +13 -3
- package/dist/startup/process-handlers.js.map +1 -1
- package/dist/util/logger.d.ts.map +1 -1
- package/dist/util/logger.js +3 -2
- package/dist/util/logger.js.map +1 -1
- package/dist/util/shutdown.d.ts +4 -0
- package/dist/util/shutdown.d.ts.map +1 -1
- package/dist/util/shutdown.js +26 -6
- package/dist/util/shutdown.js.map +1 -1
- package/dist/util/stdio-safety.d.ts +3 -0
- package/dist/util/stdio-safety.d.ts.map +1 -0
- package/dist/util/stdio-safety.js +20 -0
- package/dist/util/stdio-safety.js.map +1 -0
- package/package.json +5 -5
package/dist/indexer/indexer.js
CHANGED
|
@@ -11,7 +11,7 @@ import { finalizeDerivedState } from "./finalize-derived-state.js";
|
|
|
11
11
|
import { watchRepositoryWithIndexer } from "./watcher.js";
|
|
12
12
|
import { IndexingConfigSchema, } from "../config/types.js";
|
|
13
13
|
import { loadConfig } from "../config/loadConfig.js";
|
|
14
|
-
import { buildDeferredIndexes, closeLadybugDb, flushStaleFinalizers, getLadybugConn, getLadybugDbPath, initLadybugDb, preIndexCheckpoint, withWriteConn, } from "../db/ladybug.js";
|
|
14
|
+
import { buildDeferredIndexes, closeLadybugDb, ensureCriticalSymbolFtsIndex, flushStaleFinalizers, getLadybugConn, getLadybugDbPath, initLadybugDb, preIndexCheckpoint, withWriteConn, } from "../db/ladybug.js";
|
|
15
15
|
import { withPostIndexWriteSession } from "../db/write-session.js";
|
|
16
16
|
import * as ladybugDb from "../db/ladybug-queries.js";
|
|
17
17
|
import { derivedStateIsStale, getDerivedState, markDerivedStateDirty, recordDerivedStateError, } from "../db/ladybug-derived-state.js";
|
|
@@ -38,7 +38,7 @@ import { flagStaleMemoriesForChangedFiles, importMemoryFilesFromDisk, } from "./
|
|
|
38
38
|
import { withIndexingGate } from "../mcp/indexing-gate.js";
|
|
39
39
|
import { isInToolDispatch, runToolDispatch, waitForToolDispatchIdle, } from "../mcp/dispatch-limiter.js";
|
|
40
40
|
import { executeProviderFirstLspIncremental, executeProviderFirstLspFull, executeProviderFirstScipIncremental, executeProviderFirstScipFull, resolveProviderFirstExecutionPlan, } from "./provider-first/executor.js";
|
|
41
|
-
import { materializeProviderFacts, providerFirstGraphRowTotal, } from "./provider-first/materializer.js";
|
|
41
|
+
import { filterProviderFactsByExcludedPaths, filterProviderRowsByExcludedPaths, materializeProviderFacts, providerFirstGraphRowTotal, } from "./provider-first/materializer.js";
|
|
42
42
|
import { collectLegacyFallbackShadowRows, mergeProviderFirstGraphRows, } from "./provider-first/legacy-shadow-rows.js";
|
|
43
43
|
import { resolveProviderFirstPipeline } from "./provider-first/planner.js";
|
|
44
44
|
import { persistProviderFirstProvenance } from "./provider-first/provenance.js";
|
|
@@ -846,6 +846,17 @@ export function resolveProviderFirstReadinessGates(params) {
|
|
|
846
846
|
shadowStagingSkipReason: params.callProofSkipReason ?? params.skippedLegacyFallbackReason,
|
|
847
847
|
};
|
|
848
848
|
}
|
|
849
|
+
export function resolveProviderFirstShadowRepoScopeSkipReason(repoId, activeRepoIds) {
|
|
850
|
+
const otherRepoIds = [
|
|
851
|
+
...new Set(activeRepoIds.filter((activeRepoId) => activeRepoId !== repoId)),
|
|
852
|
+
].sort();
|
|
853
|
+
if (otherRepoIds.length === 0)
|
|
854
|
+
return undefined;
|
|
855
|
+
const sample = otherRepoIds.slice(0, 3).join(", ");
|
|
856
|
+
const omitted = otherRepoIds.length > 3 ? ` (+${otherRepoIds.length - 3} more)` : "";
|
|
857
|
+
return ("shadow staging skipped because provider-first shadow DBs are " +
|
|
858
|
+
`single-repo scoped and the active DB contains other repo(s): ${sample}${omitted}`);
|
|
859
|
+
}
|
|
849
860
|
function skippedProviderFirstShadowBuild(params) {
|
|
850
861
|
return {
|
|
851
862
|
status: "skipped",
|
|
@@ -969,88 +980,6 @@ export function clearProviderGraphRowsForGc(rows) {
|
|
|
969
980
|
rows.edges.length = 0;
|
|
970
981
|
rows.changedFileIds.clear();
|
|
971
982
|
}
|
|
972
|
-
function filterProviderRowsByExcludedPaths(rows, excludedPaths) {
|
|
973
|
-
if (excludedPaths.size === 0)
|
|
974
|
-
return rows;
|
|
975
|
-
const files = rows.files.filter((file) => !excludedPaths.has(file.relPath));
|
|
976
|
-
const keptFileIds = new Set(files.map((file) => file.fileId));
|
|
977
|
-
const symbols = rows.symbols.filter((symbol) => keptFileIds.has(symbol.fileId));
|
|
978
|
-
const internalSymbolIds = new Set(symbols.map((symbol) => symbol.symbolId));
|
|
979
|
-
const externalSymbolIds = new Set(rows.externalSymbols.map((symbol) => symbol.symbolId));
|
|
980
|
-
const allowedSymbolIds = new Set([
|
|
981
|
-
...internalSymbolIds,
|
|
982
|
-
...externalSymbolIds,
|
|
983
|
-
]);
|
|
984
|
-
const edges = rows.edges.filter((edge) => allowedSymbolIds.has(edge.fromSymbolId) &&
|
|
985
|
-
allowedSymbolIds.has(edge.toSymbolId) &&
|
|
986
|
-
(internalSymbolIds.has(edge.fromSymbolId) ||
|
|
987
|
-
internalSymbolIds.has(edge.toSymbolId)));
|
|
988
|
-
const referencedExternalSymbolIds = new Set();
|
|
989
|
-
for (const edge of edges) {
|
|
990
|
-
if (externalSymbolIds.has(edge.fromSymbolId)) {
|
|
991
|
-
referencedExternalSymbolIds.add(edge.fromSymbolId);
|
|
992
|
-
}
|
|
993
|
-
if (externalSymbolIds.has(edge.toSymbolId)) {
|
|
994
|
-
referencedExternalSymbolIds.add(edge.toSymbolId);
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
const externalSymbols = rows.externalSymbols.filter((symbol) => referencedExternalSymbolIds.has(symbol.symbolId));
|
|
998
|
-
return {
|
|
999
|
-
files,
|
|
1000
|
-
symbols,
|
|
1001
|
-
externalSymbols,
|
|
1002
|
-
edges,
|
|
1003
|
-
changedFileIds: new Set(files.map((file) => file.fileId)),
|
|
1004
|
-
};
|
|
1005
|
-
}
|
|
1006
|
-
function filterProviderFactsByExcludedPaths(facts, excludedPaths) {
|
|
1007
|
-
const filePathAllowed = (relPath) => !excludedPaths.has(normalizePath(relPath));
|
|
1008
|
-
const files = facts.files.filter((fact) => filePathAllowed(fact.relPath));
|
|
1009
|
-
const symbols = facts.symbols.filter((fact) => filePathAllowed(fact.relPath));
|
|
1010
|
-
const internalSymbolIds = new Set(symbols.map((symbol) => symbol.symbolId));
|
|
1011
|
-
const externalSymbolIds = new Set(facts.externalSymbols.map((symbol) => symbol.symbolId));
|
|
1012
|
-
const allowedSymbolIds = new Set([
|
|
1013
|
-
...internalSymbolIds,
|
|
1014
|
-
...externalSymbolIds,
|
|
1015
|
-
]);
|
|
1016
|
-
const edges = facts.edges.filter((edge) => allowedSymbolIds.has(edge.sourceSymbolId) &&
|
|
1017
|
-
allowedSymbolIds.has(edge.targetSymbolId) &&
|
|
1018
|
-
(internalSymbolIds.has(edge.sourceSymbolId) ||
|
|
1019
|
-
internalSymbolIds.has(edge.targetSymbolId)));
|
|
1020
|
-
const referencedExternalSymbolIds = new Set();
|
|
1021
|
-
for (const edge of edges) {
|
|
1022
|
-
if (externalSymbolIds.has(edge.sourceSymbolId)) {
|
|
1023
|
-
referencedExternalSymbolIds.add(edge.sourceSymbolId);
|
|
1024
|
-
}
|
|
1025
|
-
if (externalSymbolIds.has(edge.targetSymbolId)) {
|
|
1026
|
-
referencedExternalSymbolIds.add(edge.targetSymbolId);
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
|
-
const externalSymbols = facts.externalSymbols.filter((symbol) => referencedExternalSymbolIds.has(symbol.symbolId));
|
|
1030
|
-
const diagnostics = facts.diagnostics.filter((fact) => filePathAllowed(fact.relPath));
|
|
1031
|
-
const coverage = facts.coverage.filter((fact) => filePathAllowed(fact.relPath));
|
|
1032
|
-
const occurrences = facts.occurrences.filter((fact) => filePathAllowed(fact.relPath));
|
|
1033
|
-
const sourceLinesByPath = facts.sourceLinesByPath &&
|
|
1034
|
-
new Map([...facts.sourceLinesByPath.entries()].filter(([relPath]) => filePathAllowed(relPath)));
|
|
1035
|
-
const providerRuns = facts.providerRuns.map((run) => ({
|
|
1036
|
-
...run,
|
|
1037
|
-
fileCount: files.length,
|
|
1038
|
-
symbolCount: symbols.length + externalSymbols.length,
|
|
1039
|
-
edgeCount: edges.length,
|
|
1040
|
-
diagnosticCount: diagnostics.length,
|
|
1041
|
-
}));
|
|
1042
|
-
return {
|
|
1043
|
-
files,
|
|
1044
|
-
symbols,
|
|
1045
|
-
occurrences,
|
|
1046
|
-
edges,
|
|
1047
|
-
externalSymbols,
|
|
1048
|
-
diagnostics,
|
|
1049
|
-
coverage,
|
|
1050
|
-
providerRuns,
|
|
1051
|
-
...(sourceLinesByPath ? { sourceLinesByPath } : {}),
|
|
1052
|
-
};
|
|
1053
|
-
}
|
|
1054
983
|
function providerRowsHaveMaterialization(rows) {
|
|
1055
984
|
return (rows.files.length > 0 ||
|
|
1056
985
|
rows.symbols.length > 0 ||
|
|
@@ -1458,6 +1387,10 @@ async function indexRepoImpl(repoId, mode, onProgress, signal, options, scipPreR
|
|
|
1458
1387
|
let providerFirstGenerationId;
|
|
1459
1388
|
const providerFirstFallbackPaths = new Set();
|
|
1460
1389
|
const providerFirstChangedFileIds = new Set();
|
|
1390
|
+
const providerFirstShadowRepoScopeSkipReason = providerFirst.selectedPipeline === "providerFirst" &&
|
|
1391
|
+
providerFirstExecutionPlan.canExecute
|
|
1392
|
+
? resolveProviderFirstShadowRepoScopeSkipReason(repoId, (await ladybugDb.listRepos(conn)).map((repo) => repo.repoId))
|
|
1393
|
+
: undefined;
|
|
1461
1394
|
let providerFirstScan;
|
|
1462
1395
|
if (providerFirst.selectedPipeline === "providerFirst") {
|
|
1463
1396
|
if (providerFirstExecutionPlan.canExecute) {
|
|
@@ -1528,6 +1461,11 @@ async function indexRepoImpl(repoId, mode, onProgress, signal, options, scipPreR
|
|
|
1528
1461
|
onProgress,
|
|
1529
1462
|
}));
|
|
1530
1463
|
recordFinalizeIndexingSubphaseTimings(finalizeResult.timings);
|
|
1464
|
+
await measurePhase("ensureCriticalSymbolFts", async () => {
|
|
1465
|
+
await ensureCriticalSymbolFtsIndex({
|
|
1466
|
+
recordTiming: recordIndexSubphaseTiming,
|
|
1467
|
+
});
|
|
1468
|
+
});
|
|
1531
1469
|
const freshConn = await getLadybugConn();
|
|
1532
1470
|
const derivedResult = params.skipDerivedStateReason
|
|
1533
1471
|
? await measurePhase("skipDerivedState", async () => {
|
|
@@ -1722,665 +1660,691 @@ async function indexRepoImpl(repoId, mode, onProgress, signal, options, scipPreR
|
|
|
1722
1660
|
providerFirstExecutor &&
|
|
1723
1661
|
providerFirstIncrementalBootstrapped) {
|
|
1724
1662
|
providerFirstTimingStartedAt = Date.now();
|
|
1725
|
-
|
|
1726
|
-
message: "scanning repository for provider-first coverage",
|
|
1727
|
-
});
|
|
1728
|
-
const providerCoverageScan = await measureProviderFirstPhase("coverageScan", "providerFirstCoverageScan", () => scanRepoForIndex({
|
|
1729
|
-
repoId,
|
|
1730
|
-
repoRoot: repoRow.rootPath,
|
|
1731
|
-
config,
|
|
1732
|
-
onProgress,
|
|
1733
|
-
deleteRemovedFiles: false,
|
|
1734
|
-
}));
|
|
1735
|
-
emitProviderFirstProgress(onProgress, "coverageScan", {
|
|
1736
|
-
stageCurrent: providerCoverageScan.files.length,
|
|
1737
|
-
stageTotal: providerCoverageScan.files.length,
|
|
1738
|
-
message: `scanned ${providerCoverageScan.files.length} file(s) for provider-first coverage`,
|
|
1739
|
-
});
|
|
1740
|
-
let providerFirstRemovedFilesDeleted = false;
|
|
1741
|
-
if (providerFirstIncrementalActive &&
|
|
1742
|
-
providerCoverageScan.removedFileIds.length > 0) {
|
|
1743
|
-
await measureProviderFirstPhase("deleteRemovedFiles", "providerFirstIncrementalDeleteRemovedFiles", () => withWriteConn(async (conn) => {
|
|
1744
|
-
await ladybugDb.withTransaction(conn, async (txConn) => {
|
|
1745
|
-
await ladybugDb.deleteFilesByIds(txConn, providerCoverageScan.removedFileIds);
|
|
1746
|
-
});
|
|
1747
|
-
}, postIndexSessionTimeoutMs));
|
|
1748
|
-
providerFirstRemovedFilesDeleted = true;
|
|
1749
|
-
}
|
|
1750
|
-
const providerChangedFiles = providerFirstIncrementalActive
|
|
1751
|
-
? providerFirstIncrementalChangedFiles(providerCoverageScan)
|
|
1752
|
-
: providerCoverageScan.files;
|
|
1753
|
-
const providerExecutionScan = providerFirstIncrementalActive
|
|
1754
|
-
? filterProviderFirstIncrementalScan(providerCoverageScan, providerChangedFiles)
|
|
1755
|
-
: providerCoverageScan;
|
|
1756
|
-
if (providerFirstIncrementalActive && providerChangedFiles.length === 0) {
|
|
1757
|
-
providerFirstScan = providerCoverageScan;
|
|
1663
|
+
try {
|
|
1758
1664
|
emitProviderFirstProgress(onProgress, "coverageScan", {
|
|
1759
|
-
|
|
1760
|
-
stageTotal: 0,
|
|
1761
|
-
message: "no changed files for provider-first incremental execution",
|
|
1665
|
+
message: "scanning repository for provider-first coverage",
|
|
1762
1666
|
});
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1667
|
+
const providerCoverageScan = await measureProviderFirstPhase("coverageScan", "providerFirstCoverageScan", () => scanRepoForIndex({
|
|
1668
|
+
repoId,
|
|
1669
|
+
repoRoot: repoRow.rootPath,
|
|
1670
|
+
config,
|
|
1671
|
+
onProgress,
|
|
1672
|
+
deleteRemovedFiles: false,
|
|
1673
|
+
}));
|
|
1674
|
+
emitProviderFirstProgress(onProgress, "coverageScan", {
|
|
1675
|
+
stageCurrent: providerCoverageScan.files.length,
|
|
1676
|
+
stageTotal: providerCoverageScan.files.length,
|
|
1677
|
+
message: `scanned ${providerCoverageScan.files.length} file(s) for provider-first coverage`,
|
|
1678
|
+
});
|
|
1679
|
+
let providerFirstRemovedFilesDeleted = false;
|
|
1680
|
+
if (providerFirstIncrementalActive &&
|
|
1681
|
+
providerCoverageScan.removedFileIds.length > 0) {
|
|
1682
|
+
await measureProviderFirstPhase("deleteRemovedFiles", "providerFirstIncrementalDeleteRemovedFiles", () => withWriteConn(async (conn) => {
|
|
1683
|
+
await ladybugDb.withTransaction(conn, async (txConn) => {
|
|
1684
|
+
await ladybugDb.deleteFilesByIds(txConn, providerCoverageScan.removedFileIds);
|
|
1685
|
+
});
|
|
1686
|
+
}, postIndexSessionTimeoutMs));
|
|
1687
|
+
providerFirstRemovedFilesDeleted = true;
|
|
1688
|
+
}
|
|
1689
|
+
const providerChangedFiles = providerFirstIncrementalActive
|
|
1690
|
+
? providerFirstIncrementalChangedFiles(providerCoverageScan)
|
|
1691
|
+
: providerCoverageScan.files;
|
|
1692
|
+
const providerExecutionScan = providerFirstIncrementalActive
|
|
1693
|
+
? filterProviderFirstIncrementalScan(providerCoverageScan, providerChangedFiles)
|
|
1694
|
+
: providerCoverageScan;
|
|
1695
|
+
if (providerFirstIncrementalActive && providerChangedFiles.length === 0) {
|
|
1696
|
+
providerFirstScan = providerCoverageScan;
|
|
1697
|
+
emitProviderFirstProgress(onProgress, "coverageScan", {
|
|
1698
|
+
stageCurrent: 0,
|
|
1699
|
+
stageTotal: 0,
|
|
1700
|
+
message: "no changed files for provider-first incremental execution",
|
|
1701
|
+
});
|
|
1702
|
+
}
|
|
1703
|
+
let providerResult;
|
|
1704
|
+
if (!providerFirstIncrementalActive || providerChangedFiles.length > 0) {
|
|
1769
1705
|
try {
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
appConfig,
|
|
1776
|
-
changedFiles: providerChangedFiles,
|
|
1777
|
-
signal,
|
|
1778
|
-
}));
|
|
1779
|
-
providerScipPreRefresh = scopedScip.diagnostics;
|
|
1780
|
-
activeScipPreRefresh = scopedScip.diagnostics;
|
|
1781
|
-
providerIncrementalTempPaths = scopedScip.tempPaths;
|
|
1782
|
-
}
|
|
1783
|
-
providerResult = await measureProviderFirstPhase("providerCollection", providerFirstLspExecutor(providerFirstExecutor)
|
|
1784
|
-
? providerFirstIncrementalActive
|
|
1785
|
-
? "providerFirstLspIncremental"
|
|
1786
|
-
: "providerFirstLspFull"
|
|
1787
|
-
: providerFirstIncrementalActive
|
|
1788
|
-
? "providerFirstScipIncremental"
|
|
1789
|
-
: "providerFirstScipFull", () => {
|
|
1790
|
-
if (providerFirstExecutor === "lspFull") {
|
|
1791
|
-
return executeProviderFirstLspFull({
|
|
1706
|
+
let providerScipPreRefresh = activeScipPreRefresh;
|
|
1707
|
+
let providerIncrementalTempPaths = [];
|
|
1708
|
+
try {
|
|
1709
|
+
if (providerFirstExecutor === "scipIncremental") {
|
|
1710
|
+
const scopedScip = await measureProviderFirstPhase("scipIncrementalGenerate", "providerFirstScipIncrementalGenerate", () => runProviderFirstIncrementalScipIo({
|
|
1792
1711
|
repoId,
|
|
1793
1712
|
repoRoot: repoRow.rootPath,
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1713
|
+
repoConfig: config,
|
|
1714
|
+
appConfig,
|
|
1715
|
+
changedFiles: providerChangedFiles,
|
|
1797
1716
|
signal,
|
|
1798
|
-
});
|
|
1717
|
+
}));
|
|
1718
|
+
providerScipPreRefresh = scopedScip.diagnostics;
|
|
1719
|
+
activeScipPreRefresh = scopedScip.diagnostics;
|
|
1720
|
+
providerIncrementalTempPaths = scopedScip.tempPaths;
|
|
1799
1721
|
}
|
|
1800
|
-
|
|
1801
|
-
|
|
1722
|
+
providerResult = await measureProviderFirstPhase("providerCollection", providerFirstLspExecutor(providerFirstExecutor)
|
|
1723
|
+
? providerFirstIncrementalActive
|
|
1724
|
+
? "providerFirstLspIncremental"
|
|
1725
|
+
: "providerFirstLspFull"
|
|
1726
|
+
: providerFirstIncrementalActive
|
|
1727
|
+
? "providerFirstScipIncremental"
|
|
1728
|
+
: "providerFirstScipFull", () => {
|
|
1729
|
+
if (providerFirstExecutor === "lspFull") {
|
|
1730
|
+
return executeProviderFirstLspFull({
|
|
1731
|
+
repoId,
|
|
1732
|
+
repoRoot: repoRow.rootPath,
|
|
1733
|
+
config: appConfig,
|
|
1734
|
+
scannedFiles: providerExecutionScan.files,
|
|
1735
|
+
recordPhaseTiming: recordProviderFirstPhaseTiming,
|
|
1736
|
+
signal,
|
|
1737
|
+
});
|
|
1738
|
+
}
|
|
1739
|
+
if (providerFirstExecutor === "lspIncremental") {
|
|
1740
|
+
return executeProviderFirstLspIncremental({
|
|
1741
|
+
repoId,
|
|
1742
|
+
repoRoot: repoRow.rootPath,
|
|
1743
|
+
config: appConfig,
|
|
1744
|
+
scannedFiles: providerExecutionScan.files,
|
|
1745
|
+
recordPhaseTiming: recordProviderFirstPhaseTiming,
|
|
1746
|
+
signal,
|
|
1747
|
+
});
|
|
1748
|
+
}
|
|
1749
|
+
const scipParams = {
|
|
1802
1750
|
repoId,
|
|
1803
1751
|
repoRoot: repoRow.rootPath,
|
|
1804
1752
|
config: appConfig,
|
|
1753
|
+
generatedIndexes: providerScipPreRefresh?.generatedIndexes,
|
|
1754
|
+
generatorFailures: providerScipPreRefresh?.failures,
|
|
1755
|
+
generatorCacheKey: providerScipPreRefresh?.cache?.key,
|
|
1756
|
+
scannedPaths: providerExecutionScan.files.map((file) => file.path),
|
|
1805
1757
|
scannedFiles: providerExecutionScan.files,
|
|
1806
1758
|
recordPhaseTiming: recordProviderFirstPhaseTiming,
|
|
1759
|
+
onProgress,
|
|
1807
1760
|
signal,
|
|
1808
|
-
}
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
scannedPaths: providerExecutionScan.files.map((file) => file.path),
|
|
1818
|
-
scannedFiles: providerExecutionScan.files,
|
|
1819
|
-
recordPhaseTiming: recordProviderFirstPhaseTiming,
|
|
1820
|
-
onProgress,
|
|
1821
|
-
signal,
|
|
1822
|
-
};
|
|
1823
|
-
return providerFirstExecutor === "scipIncremental"
|
|
1824
|
-
? executeProviderFirstScipIncremental(scipParams)
|
|
1825
|
-
: executeProviderFirstScipFull(scipParams);
|
|
1826
|
-
});
|
|
1827
|
-
}
|
|
1828
|
-
finally {
|
|
1829
|
-
await cleanupProviderFirstIncrementalTempPaths(providerIncrementalTempPaths);
|
|
1830
|
-
}
|
|
1831
|
-
}
|
|
1832
|
-
catch (err) {
|
|
1833
|
-
if (err instanceof ProviderFirstGraphValidationError) {
|
|
1834
|
-
throw err;
|
|
1761
|
+
};
|
|
1762
|
+
return providerFirstExecutor === "scipIncremental"
|
|
1763
|
+
? executeProviderFirstScipIncremental(scipParams)
|
|
1764
|
+
: executeProviderFirstScipFull(scipParams);
|
|
1765
|
+
});
|
|
1766
|
+
}
|
|
1767
|
+
finally {
|
|
1768
|
+
await cleanupProviderFirstIncrementalTempPaths(providerIncrementalTempPaths);
|
|
1769
|
+
}
|
|
1835
1770
|
}
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
const
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1771
|
+
catch (err) {
|
|
1772
|
+
if (err instanceof ProviderFirstGraphValidationError) {
|
|
1773
|
+
throw err;
|
|
1774
|
+
}
|
|
1775
|
+
const reason = err instanceof Error
|
|
1776
|
+
? err.message
|
|
1777
|
+
: `provider-first SCIP execution failed: ${String(err)}`;
|
|
1778
|
+
if (providerFirst.requestedMode === "auto") {
|
|
1779
|
+
const fallbackReason = formatProviderFirstAutoFallbackReason({
|
|
1780
|
+
reason,
|
|
1781
|
+
providerFirstIncrementalActive,
|
|
1782
|
+
});
|
|
1783
|
+
logger.warn("indexRepo: provider-first execution failed, using legacy fallback", {
|
|
1784
|
+
repoId,
|
|
1785
|
+
reason: fallbackReason,
|
|
1786
|
+
});
|
|
1787
|
+
providerFirstExecutionFallback = providerFirstFallbackSummary([
|
|
1788
|
+
fallbackReason,
|
|
1789
|
+
]);
|
|
1790
|
+
if (providerFirstIncrementalActive) {
|
|
1791
|
+
// Keep provider-first incremental failures scoped; otherwise the
|
|
1792
|
+
// legacy safety fallback degenerates into a full repo pass.
|
|
1793
|
+
providerFirstScan = providerExecutionScan;
|
|
1794
|
+
for (const file of providerExecutionScan.files) {
|
|
1795
|
+
providerFirstFallbackPaths.add(file.path);
|
|
1796
|
+
}
|
|
1797
|
+
providerFirstLegacyFallbackComplete = true;
|
|
1798
|
+
providerFirstLegacyFallbackFileCount = providerExecutionScan.files.length;
|
|
1799
|
+
providerFirstLegacyFallbackSamplePaths = providerExecutionScan.files
|
|
1800
|
+
.map((file) => file.path)
|
|
1801
|
+
.slice(0, 10);
|
|
1802
|
+
providerFirstLegacyFallbackStartedAt = Date.now();
|
|
1857
1803
|
}
|
|
1858
|
-
providerFirstLegacyFallbackComplete = true;
|
|
1859
|
-
providerFirstLegacyFallbackFileCount = providerExecutionScan.files.length;
|
|
1860
|
-
providerFirstLegacyFallbackSamplePaths = providerExecutionScan.files
|
|
1861
|
-
.map((file) => file.path)
|
|
1862
|
-
.slice(0, 10);
|
|
1863
|
-
providerFirstLegacyFallbackStartedAt = Date.now();
|
|
1864
1804
|
}
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1805
|
+
else {
|
|
1806
|
+
throw err;
|
|
1807
|
+
}
|
|
1868
1808
|
}
|
|
1869
1809
|
}
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1810
|
+
if (providerResult) {
|
|
1811
|
+
const executionFailureReasons = providerFirstFatalFailureReasons({
|
|
1812
|
+
failures: "failures" in providerResult ? providerResult.failures : [],
|
|
1813
|
+
providerRowsAvailable: providerResult.rows.files.length > 0,
|
|
1814
|
+
});
|
|
1815
|
+
if (executionFailureReasons.length > 0) {
|
|
1816
|
+
if (providerFirst.requestedMode === "auto") {
|
|
1817
|
+
logger.warn("indexRepo: provider-first execution had failures, using legacy fallback", {
|
|
1818
|
+
repoId,
|
|
1819
|
+
reasons: executionFailureReasons,
|
|
1820
|
+
});
|
|
1821
|
+
providerFirstExecutionFallback = providerFirstFallbackSummary(executionFailureReasons);
|
|
1822
|
+
}
|
|
1823
|
+
else {
|
|
1824
|
+
throw new Error(`Provider-first indexing cannot execute for ${repoId}: ${executionFailureReasons.join("; ")}`);
|
|
1825
|
+
}
|
|
1883
1826
|
}
|
|
1884
1827
|
else {
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1828
|
+
const providerScan = providerExecutionScan;
|
|
1829
|
+
providerFirstScan = providerScan;
|
|
1830
|
+
if (providerFactsShouldDropCoveragePayloads(providerResult.facts)) {
|
|
1831
|
+
clearProviderFactPayloadsForCoverageAnalysis(providerResult.facts);
|
|
1832
|
+
emitProviderFirstProgress(onProgress, "coverageAnalyze", {
|
|
1833
|
+
message: "large provider occurrence payloads released",
|
|
1834
|
+
});
|
|
1835
|
+
}
|
|
1836
|
+
const scanScopedProvider = filterProviderFirstDataToScannedScope({
|
|
1837
|
+
rows: providerResult.rows,
|
|
1838
|
+
facts: providerResult.facts,
|
|
1839
|
+
scannedPaths: providerScan.files.map((file) => file.path),
|
|
1840
|
+
});
|
|
1893
1841
|
emitProviderFirstProgress(onProgress, "coverageAnalyze", {
|
|
1894
|
-
message: "
|
|
1842
|
+
message: "provider rows filtered to scan scope",
|
|
1895
1843
|
});
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
const scanHasCppSemanticPaths = providerScan.files.some((file) => isCppSemanticScanPath(file.path));
|
|
1907
|
-
const semanticEligiblePaths = scanHasCppSemanticPaths
|
|
1908
|
-
? await resolveProviderFirstSemanticEligiblePaths({
|
|
1909
|
-
repoRoot: repoRow.rootPath,
|
|
1844
|
+
const scanScopedProviderPaths = scanScopedProvider.rows.files.map((file) => file.relPath);
|
|
1845
|
+
const scanHasCppSemanticPaths = providerScan.files.some((file) => isCppSemanticScanPath(file.path));
|
|
1846
|
+
const semanticEligiblePaths = scanHasCppSemanticPaths
|
|
1847
|
+
? await resolveProviderFirstSemanticEligiblePaths({
|
|
1848
|
+
repoRoot: repoRow.rootPath,
|
|
1849
|
+
scannedPaths: providerScan.files.map((file) => file.path),
|
|
1850
|
+
providerPaths: scanScopedProviderPaths,
|
|
1851
|
+
})
|
|
1852
|
+
: undefined;
|
|
1853
|
+
const coverageReport = analyzeProviderFirstCoverage({
|
|
1910
1854
|
scannedPaths: providerScan.files.map((file) => file.path),
|
|
1855
|
+
semanticEligiblePaths: semanticEligiblePaths && semanticEligiblePaths.size > 0
|
|
1856
|
+
? semanticEligiblePaths
|
|
1857
|
+
: undefined,
|
|
1911
1858
|
providerPaths: scanScopedProviderPaths,
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
semanticEligiblePaths: semanticEligiblePaths && semanticEligiblePaths.size > 0
|
|
1917
|
-
? semanticEligiblePaths
|
|
1918
|
-
: undefined,
|
|
1919
|
-
providerPaths: scanScopedProviderPaths,
|
|
1920
|
-
coverage: scanScopedProvider.facts.coverage,
|
|
1921
|
-
symbols: scanScopedProvider.facts.symbols,
|
|
1922
|
-
occurrences: scanScopedProvider.facts.occurrences,
|
|
1923
|
-
sourceLinesByPath: scanScopedProvider.facts.sourceLinesByPath,
|
|
1924
|
-
});
|
|
1925
|
-
emitProviderFirstProgress(onProgress, "coverageAnalyze", {
|
|
1926
|
-
message: "provider coverage analyzed",
|
|
1927
|
-
});
|
|
1928
|
-
if (coverageReport.fatalReasons.length > 0) {
|
|
1929
|
-
throw new Error(`Provider-first indexing cannot execute for ${repoId}: ${coverageReport.fatalReasons.join("; ")}`);
|
|
1930
|
-
}
|
|
1931
|
-
else {
|
|
1932
|
-
const legacyFallbackPlan = resolveProviderFirstLegacyFallbackPlan({
|
|
1933
|
-
fallbackFileCount: coverageReport.fallbackPaths.size,
|
|
1934
|
-
semanticEligibleFallbackFileCount: coverageReport.summary.semanticEligibilityGap?.totalFiles,
|
|
1935
|
-
maxLegacyFallbackFiles: providerFirstConfig.maxLegacyFallbackFiles,
|
|
1936
|
-
maxSemanticEligibleFallbackFiles: providerFirstConfig.maxSemanticEligibleFallbackFiles,
|
|
1859
|
+
coverage: scanScopedProvider.facts.coverage,
|
|
1860
|
+
symbols: scanScopedProvider.facts.symbols,
|
|
1861
|
+
occurrences: scanScopedProvider.facts.occurrences,
|
|
1862
|
+
sourceLinesByPath: scanScopedProvider.facts.sourceLinesByPath,
|
|
1937
1863
|
});
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
callProofSkipReason: callProofSkipDerivedStateReason(coverageReport.callProofIncompletePaths),
|
|
1941
|
-
skippedLegacyFallbackReason,
|
|
1864
|
+
emitProviderFirstProgress(onProgress, "coverageAnalyze", {
|
|
1865
|
+
message: "provider coverage analyzed",
|
|
1942
1866
|
});
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
providerFirstShadowStagingSkipReason =
|
|
1946
|
-
readinessGates.shadowStagingSkipReason;
|
|
1947
|
-
if (scopedSourceFileListActive) {
|
|
1948
|
-
providerFirstShadowStagingSkipReason =
|
|
1949
|
-
providerFirstShadowStagingSkipReason
|
|
1950
|
-
? `${providerFirstShadowStagingSkipReason}; ${scopedSourceFileListReason}`
|
|
1951
|
-
: scopedSourceFileListReason;
|
|
1867
|
+
if (coverageReport.fatalReasons.length > 0) {
|
|
1868
|
+
throw new Error(`Provider-first indexing cannot execute for ${repoId}: ${coverageReport.fatalReasons.join("; ")}`);
|
|
1952
1869
|
}
|
|
1953
|
-
|
|
1954
|
-
const
|
|
1870
|
+
else {
|
|
1871
|
+
const legacyFallbackPlan = resolveProviderFirstLegacyFallbackPlan({
|
|
1872
|
+
fallbackFileCount: coverageReport.fallbackPaths.size,
|
|
1873
|
+
semanticEligibleFallbackFileCount: coverageReport.summary.semanticEligibilityGap?.totalFiles,
|
|
1874
|
+
maxLegacyFallbackFiles: providerFirstConfig.maxLegacyFallbackFiles,
|
|
1875
|
+
maxSemanticEligibleFallbackFiles: providerFirstConfig.maxSemanticEligibleFallbackFiles,
|
|
1876
|
+
});
|
|
1877
|
+
const skippedLegacyFallbackReason = skippedProviderFirstLegacyFallbackReason(legacyFallbackPlan);
|
|
1878
|
+
const readinessGates = resolveProviderFirstReadinessGates({
|
|
1879
|
+
callProofSkipReason: callProofSkipDerivedStateReason(coverageReport.callProofIncompletePaths),
|
|
1880
|
+
skippedLegacyFallbackReason,
|
|
1881
|
+
});
|
|
1882
|
+
providerFirstSkipDerivedStateReason =
|
|
1883
|
+
readinessGates.skipDerivedStateReason;
|
|
1955
1884
|
providerFirstShadowStagingSkipReason =
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
semanticEligiblePaths,
|
|
1963
|
-
parsedFiles: legacyFallbackPlan.parsedFiles,
|
|
1964
|
-
});
|
|
1965
|
-
const providerRowsExcludedByLegacyFallback = legacyFallbackPlan.runLegacyFallback
|
|
1966
|
-
? selectProviderRowsExcludedByLegacyFallback({
|
|
1967
|
-
fallbackPaths: legacyFallbackPaths,
|
|
1968
|
-
coverage: scanScopedProvider.facts.coverage,
|
|
1969
|
-
})
|
|
1970
|
-
: new Set();
|
|
1971
|
-
const materializedRows = filterProviderRowsForFallback(scanScopedProvider.rows, providerRowsExcludedByLegacyFallback);
|
|
1972
|
-
await measureProviderFirstPhase("persistProvenance", "providerFirstPersistProvenance", () => withWriteConn((conn) => persistProviderFirstProvenance(conn, scanScopedProvider.facts)));
|
|
1973
|
-
// The provider fact set can include every SCIP occurrence and source
|
|
1974
|
-
// line. Drop it before legacy fallback and versioning so large repos
|
|
1975
|
-
// do not carry decoded provider payloads into post-index finalization.
|
|
1976
|
-
clearProviderFactPayloadsForGc(providerResult.facts);
|
|
1977
|
-
if (scanScopedProvider.facts !== providerResult.facts) {
|
|
1978
|
-
clearProviderFactPayloadsForGc(scanScopedProvider.facts);
|
|
1979
|
-
}
|
|
1980
|
-
if (providerResult.rows !== materializedRows) {
|
|
1981
|
-
clearProviderGraphRowsForGc(providerResult.rows);
|
|
1982
|
-
}
|
|
1983
|
-
if (scanScopedProvider.rows !== materializedRows &&
|
|
1984
|
-
scanScopedProvider.rows !== providerResult.rows) {
|
|
1985
|
-
clearProviderGraphRowsForGc(scanScopedProvider.rows);
|
|
1986
|
-
}
|
|
1987
|
-
await measureProviderFirstPhase("postProviderGc", "providerFirstPostProviderGc", () => flushProviderFirstPayloadFinalizers());
|
|
1988
|
-
emitProviderFirstProgress(onProgress, "coverageAnalyze", {
|
|
1989
|
-
message: "provider payload finalizers flushed",
|
|
1990
|
-
});
|
|
1991
|
-
providerFirstProviderRows = materializedRows;
|
|
1992
|
-
providerFirstGenerationId = providerResult.generationId;
|
|
1993
|
-
applyScannedFileMetadataToProviderRows({
|
|
1994
|
-
rows: materializedRows,
|
|
1995
|
-
scannedFiles: providerScan.files,
|
|
1996
|
-
});
|
|
1997
|
-
let shadowBuild;
|
|
1998
|
-
if (!legacyFallbackPlan.runLegacyFallback) {
|
|
1999
|
-
if (providerFirstShadowStagingSkipReason) {
|
|
2000
|
-
const shadowStageTotal = providerFirstGraphRowTotal(materializedRows);
|
|
2001
|
-
emitProviderFirstProgress(onProgress, "shadowStage", {
|
|
2002
|
-
stageCurrent: 0,
|
|
2003
|
-
stageTotal: shadowStageTotal,
|
|
2004
|
-
message: `shadow staging skipped: ${providerFirstShadowStagingSkipReason}`,
|
|
2005
|
-
});
|
|
2006
|
-
shadowBuild = skippedProviderFirstShadowBuild({
|
|
2007
|
-
generationId: providerResult.generationId,
|
|
2008
|
-
activation: providerFirstConfig.activation,
|
|
2009
|
-
requestedFormat: providerFirstConfig.stagingFormat,
|
|
2010
|
-
rows: materializedRows,
|
|
2011
|
-
reason: providerFirstShadowStagingSkipReason,
|
|
2012
|
-
});
|
|
1885
|
+
readinessGates.shadowStagingSkipReason;
|
|
1886
|
+
if (scopedSourceFileListActive) {
|
|
1887
|
+
providerFirstShadowStagingSkipReason =
|
|
1888
|
+
providerFirstShadowStagingSkipReason
|
|
1889
|
+
? `${providerFirstShadowStagingSkipReason}; ${scopedSourceFileListReason}`
|
|
1890
|
+
: scopedSourceFileListReason;
|
|
2013
1891
|
}
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
1892
|
+
if (providerFirstShadowRepoScopeSkipReason) {
|
|
1893
|
+
// ponytail: revisit multi-repo shadow DBs when shadow builds can copy
|
|
1894
|
+
// a complete DB, including non-target repos, before activation.
|
|
1895
|
+
providerFirstShadowStagingSkipReason =
|
|
1896
|
+
providerFirstShadowStagingSkipReason
|
|
1897
|
+
? `${providerFirstShadowStagingSkipReason}; ${providerFirstShadowRepoScopeSkipReason}`
|
|
1898
|
+
: providerFirstShadowRepoScopeSkipReason;
|
|
1899
|
+
}
|
|
1900
|
+
if (providerFirstIncrementalActive) {
|
|
1901
|
+
const incrementalShadowSkipReason = "shadow staging skipped because provider-first incremental materializes only changed files";
|
|
1902
|
+
providerFirstShadowStagingSkipReason =
|
|
1903
|
+
providerFirstShadowStagingSkipReason
|
|
1904
|
+
? `${providerFirstShadowStagingSkipReason}; ${incrementalShadowSkipReason}`
|
|
1905
|
+
: incrementalShadowSkipReason;
|
|
1906
|
+
}
|
|
1907
|
+
const legacyFallbackPaths = selectProviderFirstLegacyFallbackPaths({
|
|
1908
|
+
fallbackPaths: coverageReport.fallbackPaths,
|
|
1909
|
+
semanticEligiblePaths,
|
|
1910
|
+
parsedFiles: legacyFallbackPlan.parsedFiles,
|
|
1911
|
+
});
|
|
1912
|
+
const providerRowsExcludedByLegacyFallback = legacyFallbackPlan.runLegacyFallback
|
|
1913
|
+
? selectProviderRowsExcludedByLegacyFallback({
|
|
1914
|
+
fallbackPaths: legacyFallbackPaths,
|
|
1915
|
+
coverage: scanScopedProvider.facts.coverage,
|
|
1916
|
+
})
|
|
1917
|
+
: new Set();
|
|
1918
|
+
const materializedRows = filterProviderRowsForFallback(scanScopedProvider.rows, providerRowsExcludedByLegacyFallback);
|
|
1919
|
+
await measureProviderFirstPhase("persistProvenance", "providerFirstPersistProvenance", () => withWriteConn((conn) => persistProviderFirstProvenance(conn, scanScopedProvider.facts)));
|
|
1920
|
+
// The provider fact set can include every SCIP occurrence and source
|
|
1921
|
+
// line. Drop it before legacy fallback and versioning so large repos
|
|
1922
|
+
// do not carry decoded provider payloads into post-index finalization.
|
|
1923
|
+
clearProviderFactPayloadsForGc(providerResult.facts);
|
|
1924
|
+
if (scanScopedProvider.facts !== providerResult.facts) {
|
|
1925
|
+
clearProviderFactPayloadsForGc(scanScopedProvider.facts);
|
|
1926
|
+
}
|
|
1927
|
+
if (providerResult.rows !== materializedRows) {
|
|
1928
|
+
clearProviderGraphRowsForGc(providerResult.rows);
|
|
1929
|
+
}
|
|
1930
|
+
if (scanScopedProvider.rows !== materializedRows &&
|
|
1931
|
+
scanScopedProvider.rows !== providerResult.rows) {
|
|
1932
|
+
clearProviderGraphRowsForGc(scanScopedProvider.rows);
|
|
1933
|
+
}
|
|
1934
|
+
await measureProviderFirstPhase("postProviderGc", "providerFirstPostProviderGc", () => flushProviderFirstPayloadFinalizers());
|
|
1935
|
+
emitProviderFirstProgress(onProgress, "coverageAnalyze", {
|
|
1936
|
+
message: "provider payload finalizers flushed",
|
|
1937
|
+
});
|
|
1938
|
+
providerFirstProviderRows = materializedRows;
|
|
1939
|
+
providerFirstGenerationId = providerResult.generationId;
|
|
1940
|
+
applyScannedFileMetadataToProviderRows({
|
|
1941
|
+
rows: materializedRows,
|
|
1942
|
+
scannedFiles: providerScan.files,
|
|
1943
|
+
});
|
|
1944
|
+
let shadowBuild;
|
|
1945
|
+
if (!legacyFallbackPlan.runLegacyFallback) {
|
|
1946
|
+
if (providerFirstShadowStagingSkipReason) {
|
|
1947
|
+
const shadowStageTotal = providerFirstGraphRowTotal(materializedRows);
|
|
1948
|
+
emitProviderFirstProgress(onProgress, "shadowStage", {
|
|
1949
|
+
stageCurrent: 0,
|
|
1950
|
+
stageTotal: shadowStageTotal,
|
|
1951
|
+
message: `shadow staging skipped: ${providerFirstShadowStagingSkipReason}`,
|
|
1952
|
+
});
|
|
1953
|
+
shadowBuild = skippedProviderFirstShadowBuild({
|
|
1954
|
+
generationId: providerResult.generationId,
|
|
1955
|
+
activation: providerFirstConfig.activation,
|
|
1956
|
+
requestedFormat: providerFirstConfig.stagingFormat,
|
|
1957
|
+
rows: materializedRows,
|
|
1958
|
+
reason: providerFirstShadowStagingSkipReason,
|
|
2040
1959
|
});
|
|
2041
|
-
|
|
2042
|
-
|
|
1960
|
+
}
|
|
1961
|
+
else {
|
|
1962
|
+
const shadowStageTotal = providerFirstGraphRowTotal(materializedRows);
|
|
2043
1963
|
emitProviderFirstProgress(onProgress, "shadowStage", {
|
|
2044
|
-
stageCurrent:
|
|
2045
|
-
stageTotal:
|
|
2046
|
-
message: "provider rows
|
|
1964
|
+
stageCurrent: 0,
|
|
1965
|
+
stageTotal: shadowStageTotal,
|
|
1966
|
+
message: "staging provider rows for shadow bulk load",
|
|
2047
1967
|
});
|
|
1968
|
+
shadowBuild = await measureProviderFirstPhase("shadowStage", "providerFirstShadowStage", () => stageProviderFirstShadowBuild({
|
|
1969
|
+
repoId,
|
|
1970
|
+
generationId: providerResult.generationId,
|
|
1971
|
+
activation: providerFirstConfig.activation,
|
|
1972
|
+
requestedFormat: providerFirstConfig.stagingFormat,
|
|
1973
|
+
activeDbPath: getLadybugDbPath(),
|
|
1974
|
+
repoRoot: repoRow.rootPath,
|
|
1975
|
+
repoConfigJson: repoRow.configJson,
|
|
1976
|
+
rows: materializedRows,
|
|
1977
|
+
}));
|
|
1978
|
+
shadowBuild.activationResult =
|
|
1979
|
+
summarizeProviderFirstShadowActivationReadiness({
|
|
1980
|
+
shadowBuild,
|
|
1981
|
+
fallbackFiles: 0,
|
|
1982
|
+
graphDerivedStateReady: providerFirstSkipDerivedStateReason === undefined,
|
|
1983
|
+
shadowContainsFinalizedGraph: false,
|
|
1984
|
+
finalizedGraphReasons: providerFirstSkipDerivedStateReason
|
|
1985
|
+
? [providerFirstSkipDerivedStateReason]
|
|
1986
|
+
: undefined,
|
|
1987
|
+
});
|
|
1988
|
+
if (shadowBuild.status === "staged") {
|
|
1989
|
+
const stagedTotal = providerFirstShadowStageTotal(shadowBuild.counts);
|
|
1990
|
+
emitProviderFirstProgress(onProgress, "shadowStage", {
|
|
1991
|
+
stageCurrent: stagedTotal,
|
|
1992
|
+
stageTotal: stagedTotal,
|
|
1993
|
+
message: "provider rows staged for shadow bulk load",
|
|
1994
|
+
});
|
|
1995
|
+
}
|
|
2048
1996
|
}
|
|
2049
1997
|
}
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
1998
|
+
const activeProviderInputHash = scopedSourceFileListActive || providerFirstIncrementalActive
|
|
1999
|
+
? null
|
|
2000
|
+
: "generatedIndexes" in providerResult
|
|
2001
|
+
? providerFirstActiveInputFingerprint(providerResult.generatedIndexes)
|
|
2002
|
+
: null;
|
|
2003
|
+
const activeProviderInputRecord = activeProviderInputHash
|
|
2004
|
+
? await ladybugDb.getScipIngestionRecord(conn, repoId, PROVIDER_FIRST_ACTIVE_INPUT_RECORD_PATH)
|
|
2055
2005
|
: null;
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
activeProviderInputMatches,
|
|
2078
|
-
existingProviderSymbolCount,
|
|
2079
|
-
});
|
|
2080
|
-
if (activeMaterializationPlan.reuseExistingProviderRows) {
|
|
2081
|
-
const deleteTotal = providerFirstMaterializePhaseTotal("deleteFileSymbols", materializedRows, activeMaterializationPlan);
|
|
2082
|
-
emitProviderFirstProgress(onProgress, "materialize.deleteFileSymbols", {
|
|
2083
|
-
stageCurrent: 0,
|
|
2084
|
-
stageTotal: deleteTotal,
|
|
2085
|
-
message: "provider active stale cleanup skipped for large symbol set",
|
|
2086
|
-
});
|
|
2087
|
-
const symbolTotal = providerFirstMaterializePhaseTotal("upsertSymbols", materializedRows, activeMaterializationPlan);
|
|
2088
|
-
emitProviderFirstProgress(onProgress, "materialize.upsertSymbols", {
|
|
2089
|
-
stageCurrent: symbolTotal,
|
|
2090
|
-
stageTotal: symbolTotal,
|
|
2091
|
-
message: "provider active rows reused for existing large symbol set",
|
|
2092
|
-
});
|
|
2093
|
-
}
|
|
2094
|
-
await measureProviderFirstPhase("materialize", "providerFirstMaterialize", () => {
|
|
2006
|
+
const activeProviderInputMatches = Boolean(activeProviderInputHash &&
|
|
2007
|
+
activeProviderInputRecord?.contentHash ===
|
|
2008
|
+
activeProviderInputHash &&
|
|
2009
|
+
activeProviderInputRecord.truncated !== true);
|
|
2010
|
+
const existingProviderSymbolCount = await countExistingScipProviderSymbols(conn, repoId);
|
|
2011
|
+
const activeMaterializationPlan = providerFirstIncrementalActive
|
|
2012
|
+
? {
|
|
2013
|
+
deleteExistingFileSymbols: true,
|
|
2014
|
+
useKnownFreshWriters: true,
|
|
2015
|
+
writeEdges: true,
|
|
2016
|
+
reuseExistingProviderRows: false,
|
|
2017
|
+
}
|
|
2018
|
+
: resolveProviderFirstActiveMaterializationPlan({
|
|
2019
|
+
existingProviderFileCount: countExistingProviderPrimaryFiles({
|
|
2020
|
+
providerFiles: materializedRows.files,
|
|
2021
|
+
existingByPath: providerScan.existingByPath,
|
|
2022
|
+
}),
|
|
2023
|
+
providerSymbolCount: materializedRows.symbols.length,
|
|
2024
|
+
activeProviderInputMatches,
|
|
2025
|
+
existingProviderSymbolCount,
|
|
2026
|
+
});
|
|
2095
2027
|
if (activeMaterializationPlan.reuseExistingProviderRows) {
|
|
2096
|
-
|
|
2028
|
+
const deleteTotal = providerFirstMaterializePhaseTotal("deleteFileSymbols", materializedRows, activeMaterializationPlan);
|
|
2029
|
+
emitProviderFirstProgress(onProgress, "materialize.deleteFileSymbols", {
|
|
2030
|
+
stageCurrent: 0,
|
|
2031
|
+
stageTotal: deleteTotal,
|
|
2032
|
+
message: "provider active stale cleanup skipped for large symbol set",
|
|
2033
|
+
});
|
|
2034
|
+
const symbolTotal = providerFirstMaterializePhaseTotal("upsertSymbols", materializedRows, activeMaterializationPlan);
|
|
2035
|
+
emitProviderFirstProgress(onProgress, "materialize.upsertSymbols", {
|
|
2036
|
+
stageCurrent: symbolTotal,
|
|
2037
|
+
stageTotal: symbolTotal,
|
|
2038
|
+
message: "provider active rows reused for existing large symbol set",
|
|
2039
|
+
});
|
|
2097
2040
|
}
|
|
2098
|
-
|
|
2099
|
-
if (
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
});
|
|
2119
|
-
const startedAt = Date.now();
|
|
2120
|
-
try {
|
|
2121
|
-
return await fn();
|
|
2122
|
-
}
|
|
2123
|
-
finally {
|
|
2124
|
-
recordProviderFirstPhaseTiming(`materialize.${phaseName}`, Date.now() - startedAt);
|
|
2041
|
+
await measureProviderFirstPhase("materialize", "providerFirstMaterialize", () => {
|
|
2042
|
+
if (activeMaterializationPlan.reuseExistingProviderRows) {
|
|
2043
|
+
return Promise.resolve();
|
|
2044
|
+
}
|
|
2045
|
+
return withWriteConn(async (conn) => {
|
|
2046
|
+
if (providerRowsHaveMaterialization(materializedRows)) {
|
|
2047
|
+
// materializeProviderFacts owns its transaction. Wrapping it
|
|
2048
|
+
// in another transaction makes large provider-first writes
|
|
2049
|
+
// crash in LadybugDB's native transaction handling.
|
|
2050
|
+
await materializeProviderFacts(conn, materializedRows, {
|
|
2051
|
+
replaceFileSymbols: true,
|
|
2052
|
+
deleteExistingFileSymbols: activeMaterializationPlan.deleteExistingFileSymbols,
|
|
2053
|
+
useKnownFreshWriters: activeMaterializationPlan.useKnownFreshWriters,
|
|
2054
|
+
writeEdges: activeMaterializationPlan.writeEdges,
|
|
2055
|
+
pruneExternalSymbols: !scopedSourceFileListActive &&
|
|
2056
|
+
!providerFirstIncrementalActive,
|
|
2057
|
+
symbolFtsIndexName: appConfig.semantic?.retrieval?.fts?.indexName,
|
|
2058
|
+
measurePhase: async (phaseName, fn) => {
|
|
2059
|
+
const substage = `materialize.${phaseName}`;
|
|
2060
|
+
const phaseTotal = providerFirstMaterializePhaseTotal(phaseName, materializedRows, activeMaterializationPlan);
|
|
2125
2061
|
emitProviderFirstProgress(onProgress, substage, {
|
|
2126
|
-
stageCurrent:
|
|
2062
|
+
stageCurrent: 0,
|
|
2127
2063
|
stageTotal: phaseTotal,
|
|
2128
|
-
message: `provider materialize ${phaseName}
|
|
2064
|
+
message: `provider materialize ${phaseName} start`,
|
|
2129
2065
|
});
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
}
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2066
|
+
const startedAt = Date.now();
|
|
2067
|
+
try {
|
|
2068
|
+
return await fn();
|
|
2069
|
+
}
|
|
2070
|
+
finally {
|
|
2071
|
+
recordProviderFirstPhaseTiming(`materialize.${phaseName}`, Date.now() - startedAt);
|
|
2072
|
+
emitProviderFirstProgress(onProgress, substage, {
|
|
2073
|
+
stageCurrent: phaseTotal,
|
|
2074
|
+
stageTotal: phaseTotal,
|
|
2075
|
+
message: `provider materialize ${phaseName} done`,
|
|
2076
|
+
});
|
|
2077
|
+
}
|
|
2078
|
+
},
|
|
2079
|
+
});
|
|
2080
|
+
}
|
|
2081
|
+
else if (!scopedSourceFileListActive &&
|
|
2082
|
+
!providerFirstIncrementalActive) {
|
|
2083
|
+
await ladybugDb.withTransaction(conn, async (txConn) => {
|
|
2084
|
+
await ladybugDb.pruneStaleScipExternalSymbols(txConn, repoId, []);
|
|
2085
|
+
});
|
|
2086
|
+
}
|
|
2087
|
+
if (!providerFirstRemovedFilesDeleted &&
|
|
2088
|
+
providerScan.removedFileIds.length > 0) {
|
|
2089
|
+
await ladybugDb.withTransaction(conn, async (txConn) => {
|
|
2090
|
+
await ladybugDb.deleteFilesByIds(txConn, providerScan.removedFileIds);
|
|
2091
|
+
});
|
|
2092
|
+
}
|
|
2093
|
+
if (activeProviderInputHash) {
|
|
2094
|
+
await ladybugDb.mergeScipIngestionRecord(conn, {
|
|
2095
|
+
id: hashValue({
|
|
2096
|
+
repoId,
|
|
2097
|
+
indexPath: PROVIDER_FIRST_ACTIVE_INPUT_RECORD_PATH,
|
|
2098
|
+
}),
|
|
2149
2099
|
repoId,
|
|
2150
2100
|
indexPath: PROVIDER_FIRST_ACTIVE_INPUT_RECORD_PATH,
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2101
|
+
contentHash: activeProviderInputHash,
|
|
2102
|
+
ingestedAt: new Date().toISOString(),
|
|
2103
|
+
ledgerVersion: providerResult.generationId,
|
|
2104
|
+
symbolCount: materializedRows.symbols.length,
|
|
2105
|
+
edgeCount: activeMaterializationPlan.writeEdges
|
|
2106
|
+
? materializedRows.edges.length
|
|
2107
|
+
: 0,
|
|
2108
|
+
externalSymbolCount: materializedRows.externalSymbols.length,
|
|
2109
|
+
truncated: !activeMaterializationPlan.writeEdges,
|
|
2110
|
+
});
|
|
2111
|
+
}
|
|
2112
|
+
}, postIndexSessionTimeoutMs);
|
|
2113
|
+
});
|
|
2114
|
+
invalidateIndexResultCaches(repoId);
|
|
2115
|
+
providerFirstScipMaterialized = true;
|
|
2116
|
+
if (activeMaterializationPlan.reuseExistingProviderRows) {
|
|
2117
|
+
providerFirstMaterializedFiles = 0;
|
|
2118
|
+
providerFirstMaterializedSymbols = 0;
|
|
2119
|
+
providerFirstMaterializedEdges = 0;
|
|
2120
|
+
}
|
|
2121
|
+
else {
|
|
2122
|
+
providerFirstMaterializedFiles = materializedRows.files.length;
|
|
2123
|
+
providerFirstMaterializedSymbols =
|
|
2124
|
+
materializedRows.symbols.length +
|
|
2125
|
+
materializedRows.externalSymbols.length;
|
|
2126
|
+
providerFirstMaterializedEdges = materializedRows.edges.length;
|
|
2127
|
+
for (const fileId of materializedRows.changedFileIds) {
|
|
2128
|
+
providerFirstChangedFileIds.add(fileId);
|
|
2164
2129
|
}
|
|
2165
|
-
}, postIndexSessionTimeoutMs);
|
|
2166
|
-
});
|
|
2167
|
-
invalidateIndexResultCaches(repoId);
|
|
2168
|
-
providerFirstScipMaterialized = true;
|
|
2169
|
-
if (activeMaterializationPlan.reuseExistingProviderRows) {
|
|
2170
|
-
providerFirstMaterializedFiles = 0;
|
|
2171
|
-
providerFirstMaterializedSymbols = 0;
|
|
2172
|
-
providerFirstMaterializedEdges = 0;
|
|
2173
|
-
}
|
|
2174
|
-
else {
|
|
2175
|
-
providerFirstMaterializedFiles = materializedRows.files.length;
|
|
2176
|
-
providerFirstMaterializedSymbols =
|
|
2177
|
-
materializedRows.symbols.length +
|
|
2178
|
-
materializedRows.externalSymbols.length;
|
|
2179
|
-
providerFirstMaterializedEdges = materializedRows.edges.length;
|
|
2180
|
-
for (const fileId of materializedRows.changedFileIds) {
|
|
2181
|
-
providerFirstChangedFileIds.add(fileId);
|
|
2182
2130
|
}
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
.
|
|
2189
|
-
executionReasons.push(`SCIP provider ignored ${scanScopedProvider.ignoredProviderPaths.length} repo-relative file(s) outside the configured scan scope: ${sample}`);
|
|
2190
|
-
}
|
|
2191
|
-
if (activeMaterializationPlan.reuseExistingProviderRows) {
|
|
2192
|
-
executionReasons.push(`active provider rows reused for ${materializedRows.symbols.length} large existing symbol row(s); clean rebuild or shadow activation is required to physically retire stale provider rows`);
|
|
2193
|
-
}
|
|
2194
|
-
if (scopedSourceFileListActive) {
|
|
2195
|
-
executionReasons.push("repo.sourceFileListPath is set; provider-first active row reuse and shadow activation are disabled so this subset run cannot masquerade as a complete graph");
|
|
2196
|
-
}
|
|
2197
|
-
if (coverageReport.fallbackPaths.size > 0) {
|
|
2198
|
-
if (legacyFallbackPlan.runLegacyFallback) {
|
|
2199
|
-
executionReasons.push(`legacy fallback indexed ${legacyFallbackPlan.parsedFiles} uncovered or provider-unusable file(s) after provider-first materialization`);
|
|
2131
|
+
const executionReasons = [...coverageReport.reasons];
|
|
2132
|
+
if (scanScopedProvider.ignoredProviderPaths.length > 0) {
|
|
2133
|
+
const sample = scanScopedProvider.ignoredProviderPaths
|
|
2134
|
+
.slice(0, 5)
|
|
2135
|
+
.join(", ");
|
|
2136
|
+
executionReasons.push(`SCIP provider ignored ${scanScopedProvider.ignoredProviderPaths.length} repo-relative file(s) outside the configured scan scope: ${sample}`);
|
|
2200
2137
|
}
|
|
2201
|
-
if (
|
|
2202
|
-
executionReasons.push(
|
|
2138
|
+
if (activeMaterializationPlan.reuseExistingProviderRows) {
|
|
2139
|
+
executionReasons.push(`active provider rows reused for ${materializedRows.symbols.length} large existing symbol row(s); clean rebuild or shadow activation is required to physically retire stale provider rows`);
|
|
2203
2140
|
}
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
...coverageReport.summary,
|
|
2207
|
-
fallbackFiles: legacyFallbackPlan.parsedFiles,
|
|
2208
|
-
};
|
|
2209
|
-
if (legacyFallbackPlan.skippedFiles > 0) {
|
|
2210
|
-
coverageSummary.legacyFallbackSkippedFiles =
|
|
2211
|
-
legacyFallbackPlan.skippedFiles;
|
|
2212
|
-
coverageSummary.legacyFallbackFileLimit =
|
|
2213
|
-
legacyFallbackPlan.fileLimit;
|
|
2214
|
-
if (legacyFallbackPlan.semanticEligibleFallbackFiles !== undefined &&
|
|
2215
|
-
legacyFallbackPlan.semanticEligibleFileLimit !== undefined) {
|
|
2216
|
-
coverageSummary.semanticEligibleFallbackFiles =
|
|
2217
|
-
legacyFallbackPlan.semanticEligibleFallbackFiles;
|
|
2218
|
-
coverageSummary.semanticEligibleFallbackFileLimit =
|
|
2219
|
-
legacyFallbackPlan.semanticEligibleFileLimit;
|
|
2141
|
+
if (scopedSourceFileListActive) {
|
|
2142
|
+
executionReasons.push("repo.sourceFileListPath is set; provider-first active row reuse and shadow activation are disabled so this subset run cannot masquerade as a complete graph");
|
|
2220
2143
|
}
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
symbolsIndexed: materializedRows.symbols.length +
|
|
2232
|
-
materializedRows.externalSymbols.length,
|
|
2233
|
-
edgesCreated: materializedRows.edges.length,
|
|
2234
|
-
externalSymbolsIndexed: materializedRows.externalSymbols.length,
|
|
2235
|
-
shadowBuild,
|
|
2236
|
-
coverage: coverageSummary,
|
|
2237
|
-
reasons: executionReasons,
|
|
2238
|
-
};
|
|
2239
|
-
if (legacyFallbackPlan.runLegacyFallback) {
|
|
2240
|
-
logger.info("indexRepo: provider-first materialized; using legacy fallback for uncovered files", {
|
|
2241
|
-
repoId,
|
|
2144
|
+
if (coverageReport.fallbackPaths.size > 0) {
|
|
2145
|
+
if (legacyFallbackPlan.runLegacyFallback) {
|
|
2146
|
+
executionReasons.push(`legacy fallback indexed ${legacyFallbackPlan.parsedFiles} uncovered or provider-unusable file(s) after provider-first materialization`);
|
|
2147
|
+
}
|
|
2148
|
+
if (skippedLegacyFallbackReason) {
|
|
2149
|
+
executionReasons.push(skippedLegacyFallbackReason);
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
const coverageSummary = {
|
|
2153
|
+
...coverageReport.summary,
|
|
2242
2154
|
fallbackFiles: legacyFallbackPlan.parsedFiles,
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2155
|
+
};
|
|
2156
|
+
if (legacyFallbackPlan.skippedFiles > 0) {
|
|
2157
|
+
coverageSummary.legacyFallbackSkippedFiles =
|
|
2158
|
+
legacyFallbackPlan.skippedFiles;
|
|
2159
|
+
coverageSummary.legacyFallbackFileLimit =
|
|
2160
|
+
legacyFallbackPlan.fileLimit;
|
|
2161
|
+
if (legacyFallbackPlan.semanticEligibleFallbackFiles !== undefined &&
|
|
2162
|
+
legacyFallbackPlan.semanticEligibleFileLimit !== undefined) {
|
|
2163
|
+
coverageSummary.semanticEligibleFallbackFiles =
|
|
2164
|
+
legacyFallbackPlan.semanticEligibleFallbackFiles;
|
|
2165
|
+
coverageSummary.semanticEligibleFallbackFileLimit =
|
|
2166
|
+
legacyFallbackPlan.semanticEligibleFileLimit;
|
|
2167
|
+
}
|
|
2248
2168
|
}
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2169
|
+
if (scanScopedProvider.ignoredProviderPaths.length > 0) {
|
|
2170
|
+
coverageSummary.ignoredProviderFiles =
|
|
2171
|
+
scanScopedProvider.ignoredProviderPaths.length;
|
|
2172
|
+
coverageSummary.ignoredProviderFileSamples =
|
|
2173
|
+
scanScopedProvider.ignoredProviderPaths.slice(0, 5);
|
|
2174
|
+
}
|
|
2175
|
+
providerFirstExecutedSummary = {
|
|
2176
|
+
...providerResult.summary,
|
|
2177
|
+
filesProcessed: materializedRows.files.length,
|
|
2178
|
+
symbolsIndexed: materializedRows.symbols.length +
|
|
2179
|
+
materializedRows.externalSymbols.length,
|
|
2180
|
+
edgesCreated: materializedRows.edges.length,
|
|
2181
|
+
externalSymbolsIndexed: materializedRows.externalSymbols.length,
|
|
2182
|
+
shadowBuild,
|
|
2183
|
+
coverage: coverageSummary,
|
|
2184
|
+
reasons: executionReasons,
|
|
2185
|
+
};
|
|
2186
|
+
if (legacyFallbackPlan.runLegacyFallback) {
|
|
2187
|
+
logger.info("indexRepo: provider-first materialized; using legacy fallback for uncovered files", {
|
|
2262
2188
|
repoId,
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
});
|
|
2266
|
-
const semanticRefresh = await runProviderFirstDeferredSemanticRefresh({
|
|
2267
|
-
versionId,
|
|
2268
|
-
semanticDeferred,
|
|
2189
|
+
fallbackFiles: legacyFallbackPlan.parsedFiles,
|
|
2190
|
+
reasons: executionReasons,
|
|
2269
2191
|
});
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2192
|
+
providerFirstScan = filterProviderFirstFallbackScan(providerScan, legacyFallbackPaths);
|
|
2193
|
+
for (const file of providerFirstScan.files) {
|
|
2194
|
+
providerFirstFallbackPaths.add(file.path);
|
|
2195
|
+
}
|
|
2196
|
+
providerFirstLegacyFallbackComplete =
|
|
2197
|
+
isProviderFirstLegacyFallbackPlanComplete(legacyFallbackPlan);
|
|
2198
|
+
providerFirstLegacyFallbackFileCount =
|
|
2199
|
+
legacyFallbackPlan.parsedFiles;
|
|
2200
|
+
providerFirstLegacyFallbackSamplePaths = [
|
|
2201
|
+
...legacyFallbackPaths,
|
|
2202
|
+
].slice(0, 10);
|
|
2203
|
+
providerFirstLegacyFallbackStartedAt = Date.now();
|
|
2204
|
+
}
|
|
2205
|
+
else {
|
|
2206
|
+
if (activeMaterializationPlan.reuseExistingProviderRows) {
|
|
2207
|
+
const versionId = await resolveActiveGraphVersionId("Provider-first SCIP active rows reused");
|
|
2208
|
+
let semanticDeferred = await markProviderFirstSemanticReadinessDeferred({
|
|
2209
|
+
repoId,
|
|
2210
|
+
versionId,
|
|
2211
|
+
appConfig,
|
|
2212
|
+
});
|
|
2213
|
+
const semanticRefresh = await runProviderFirstDeferredSemanticRefresh({
|
|
2214
|
+
versionId,
|
|
2215
|
+
semanticDeferred,
|
|
2216
|
+
});
|
|
2217
|
+
semanticDeferred = semanticRefresh.semanticDeferred;
|
|
2218
|
+
providerFirstExecutedSummary = withProviderFirstPhaseTimings(providerFirstExecutedSummary);
|
|
2219
|
+
const resultScip = "generatedIndexes" in providerResult
|
|
2220
|
+
? {
|
|
2221
|
+
generatedIndexes: providerResult.generatedIndexes,
|
|
2222
|
+
failures: providerResult.failures,
|
|
2223
|
+
generatorCache: activeScipPreRefresh?.cache,
|
|
2224
|
+
}
|
|
2225
|
+
: undefined;
|
|
2226
|
+
const result = {
|
|
2227
|
+
versionId,
|
|
2228
|
+
filesProcessed: 0,
|
|
2229
|
+
changedFiles: 0,
|
|
2230
|
+
removedFiles: 0,
|
|
2231
|
+
symbolsIndexed: 0,
|
|
2232
|
+
edgesCreated: 0,
|
|
2233
|
+
clustersComputed: 0,
|
|
2234
|
+
processesTraced: 0,
|
|
2235
|
+
durationMs: Date.now() - startTime,
|
|
2236
|
+
pass1Engine: emptyPass1EngineTelemetry(),
|
|
2237
|
+
scip: resultScip,
|
|
2238
|
+
providerFirst,
|
|
2239
|
+
providerFirstExecution: providerFirstExecutedSummary,
|
|
2240
|
+
semanticDeferred: semanticDeferred || undefined,
|
|
2241
|
+
algorithmRefresh: skippedDerivedStateResult("provider-first active rows reused").algorithmRefresh,
|
|
2242
|
+
};
|
|
2243
|
+
clearProviderGraphRowsForGc(materializedRows);
|
|
2244
|
+
return result;
|
|
2245
|
+
}
|
|
2246
|
+
const versionId = await createOrReuseVersion(providerFirstLspExecutor(providerResult.summary.executor)
|
|
2247
|
+
? providerFirstIncrementalActive
|
|
2248
|
+
? "Provider-first LSP incremental index"
|
|
2249
|
+
: "Provider-first LSP index"
|
|
2250
|
+
: providerFirstIncrementalActive
|
|
2251
|
+
? "Provider-first SCIP incremental index"
|
|
2252
|
+
: "Provider-first SCIP index", true);
|
|
2253
|
+
const pass1Engine = emptyPass1EngineTelemetry();
|
|
2254
|
+
const scip = "generatedIndexes" in providerResult
|
|
2273
2255
|
? {
|
|
2274
2256
|
generatedIndexes: providerResult.generatedIndexes,
|
|
2275
2257
|
failures: providerResult.failures,
|
|
2276
2258
|
generatorCache: activeScipPreRefresh?.cache,
|
|
2277
2259
|
}
|
|
2278
2260
|
: undefined;
|
|
2261
|
+
const post = await runPostIndexFinalization({
|
|
2262
|
+
versionId,
|
|
2263
|
+
indexMode: providerFirstIncrementalActive ? "incremental" : "full",
|
|
2264
|
+
filesTotal: providerFirstIncrementalActive
|
|
2265
|
+
? providerCoverageScan.files.length
|
|
2266
|
+
: materializedRows.files.length,
|
|
2267
|
+
filesScanned: materializedRows.files.length,
|
|
2268
|
+
symbolsExtracted: materializedRows.symbols.length +
|
|
2269
|
+
materializedRows.externalSymbols.length,
|
|
2270
|
+
edgesExtracted: materializedRows.edges.length,
|
|
2271
|
+
changedFileIdsForFinalize: scopedSourceFileListActive || providerFirstIncrementalActive
|
|
2272
|
+
? materializedRows.changedFileIds
|
|
2273
|
+
: undefined,
|
|
2274
|
+
changedTestFilePathsForFinalize: new Set(),
|
|
2275
|
+
changedFileIdsForMemory: materializedRows.changedFileIds,
|
|
2276
|
+
hasIndexMutations: true,
|
|
2277
|
+
callResolutionTelemetry: createCallResolutionTelemetry({
|
|
2278
|
+
repoId,
|
|
2279
|
+
mode: providerFirstIncrementalActive ? "incremental" : "full",
|
|
2280
|
+
pass2EligibleFileCount: 0,
|
|
2281
|
+
registeredResolvers: [],
|
|
2282
|
+
}),
|
|
2283
|
+
pass1Engine,
|
|
2284
|
+
scip,
|
|
2285
|
+
preloadedFileSummarySymbolFactsByFile: buildPreloadedFileSummarySymbolFactsFromRows({
|
|
2286
|
+
files: materializedRows.files,
|
|
2287
|
+
symbols: materializedRows.symbols,
|
|
2288
|
+
}),
|
|
2289
|
+
deferSemanticRefresh: true,
|
|
2290
|
+
skipDerivedStateReason: providerFirstSkipDerivedStateReason,
|
|
2291
|
+
});
|
|
2292
|
+
providerFirstExecutedSummary = {
|
|
2293
|
+
...providerFirstExecutedSummary,
|
|
2294
|
+
shadowBuild: await finalizeProviderFirstShadowBuild(providerFirstExecutedSummary.shadowBuild, versionId, post.semanticDeferred),
|
|
2295
|
+
};
|
|
2296
|
+
const semanticRefresh = await runProviderFirstDeferredSemanticRefresh({
|
|
2297
|
+
versionId,
|
|
2298
|
+
semanticDeferred: post.semanticDeferred,
|
|
2299
|
+
});
|
|
2300
|
+
providerFirstExecutedSummary = withProviderFirstPhaseTimings(providerFirstExecutedSummary);
|
|
2279
2301
|
const result = {
|
|
2280
2302
|
versionId,
|
|
2281
|
-
filesProcessed:
|
|
2282
|
-
changedFiles:
|
|
2283
|
-
removedFiles:
|
|
2284
|
-
symbolsIndexed:
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2303
|
+
filesProcessed: materializedRows.files.length,
|
|
2304
|
+
changedFiles: materializedRows.changedFileIds.size,
|
|
2305
|
+
removedFiles: providerScan.removedFiles,
|
|
2306
|
+
symbolsIndexed: materializedRows.symbols.length +
|
|
2307
|
+
materializedRows.externalSymbols.length,
|
|
2308
|
+
edgesCreated: materializedRows.edges.length,
|
|
2309
|
+
clustersComputed: post.clustersComputed,
|
|
2310
|
+
processesTraced: post.processesTraced,
|
|
2288
2311
|
durationMs: Date.now() - startTime,
|
|
2289
|
-
|
|
2290
|
-
|
|
2312
|
+
summaryStats: semanticRefresh.summaryStats ?? post.summaryStats,
|
|
2313
|
+
timings: phaseTimings
|
|
2314
|
+
? {
|
|
2315
|
+
totalMs: Date.now() - startTime,
|
|
2316
|
+
phases: phaseTimings,
|
|
2317
|
+
}
|
|
2318
|
+
: undefined,
|
|
2319
|
+
pass1Engine,
|
|
2320
|
+
scip,
|
|
2291
2321
|
providerFirst,
|
|
2292
2322
|
providerFirstExecution: providerFirstExecutedSummary,
|
|
2293
|
-
semanticDeferred: semanticDeferred
|
|
2294
|
-
algorithmRefresh:
|
|
2323
|
+
semanticDeferred: semanticRefresh.semanticDeferred,
|
|
2324
|
+
algorithmRefresh: post.algorithmRefresh,
|
|
2295
2325
|
};
|
|
2296
|
-
clearProviderGraphRowsForGc(materializedRows);
|
|
2297
2326
|
return result;
|
|
2298
2327
|
}
|
|
2299
|
-
const versionId = await createOrReuseVersion(providerFirstLspExecutor(providerResult.summary.executor)
|
|
2300
|
-
? providerFirstIncrementalActive
|
|
2301
|
-
? "Provider-first LSP incremental index"
|
|
2302
|
-
: "Provider-first LSP index"
|
|
2303
|
-
: providerFirstIncrementalActive
|
|
2304
|
-
? "Provider-first SCIP incremental index"
|
|
2305
|
-
: "Provider-first SCIP index", true);
|
|
2306
|
-
const pass1Engine = emptyPass1EngineTelemetry();
|
|
2307
|
-
const scip = "generatedIndexes" in providerResult
|
|
2308
|
-
? {
|
|
2309
|
-
generatedIndexes: providerResult.generatedIndexes,
|
|
2310
|
-
failures: providerResult.failures,
|
|
2311
|
-
generatorCache: activeScipPreRefresh?.cache,
|
|
2312
|
-
}
|
|
2313
|
-
: undefined;
|
|
2314
|
-
const post = await runPostIndexFinalization({
|
|
2315
|
-
versionId,
|
|
2316
|
-
indexMode: providerFirstIncrementalActive ? "incremental" : "full",
|
|
2317
|
-
filesTotal: providerFirstIncrementalActive
|
|
2318
|
-
? providerCoverageScan.files.length
|
|
2319
|
-
: materializedRows.files.length,
|
|
2320
|
-
filesScanned: materializedRows.files.length,
|
|
2321
|
-
symbolsExtracted: materializedRows.symbols.length +
|
|
2322
|
-
materializedRows.externalSymbols.length,
|
|
2323
|
-
edgesExtracted: materializedRows.edges.length,
|
|
2324
|
-
changedFileIdsForFinalize: scopedSourceFileListActive || providerFirstIncrementalActive
|
|
2325
|
-
? materializedRows.changedFileIds
|
|
2326
|
-
: undefined,
|
|
2327
|
-
changedTestFilePathsForFinalize: new Set(),
|
|
2328
|
-
changedFileIdsForMemory: materializedRows.changedFileIds,
|
|
2329
|
-
hasIndexMutations: true,
|
|
2330
|
-
callResolutionTelemetry: createCallResolutionTelemetry({
|
|
2331
|
-
repoId,
|
|
2332
|
-
mode: providerFirstIncrementalActive ? "incremental" : "full",
|
|
2333
|
-
pass2EligibleFileCount: 0,
|
|
2334
|
-
registeredResolvers: [],
|
|
2335
|
-
}),
|
|
2336
|
-
pass1Engine,
|
|
2337
|
-
scip,
|
|
2338
|
-
preloadedFileSummarySymbolFactsByFile: buildPreloadedFileSummarySymbolFactsFromRows({
|
|
2339
|
-
files: materializedRows.files,
|
|
2340
|
-
symbols: materializedRows.symbols,
|
|
2341
|
-
}),
|
|
2342
|
-
deferSemanticRefresh: true,
|
|
2343
|
-
skipDerivedStateReason: providerFirstSkipDerivedStateReason,
|
|
2344
|
-
});
|
|
2345
|
-
providerFirstExecutedSummary = {
|
|
2346
|
-
...providerFirstExecutedSummary,
|
|
2347
|
-
shadowBuild: await finalizeProviderFirstShadowBuild(providerFirstExecutedSummary.shadowBuild, versionId, post.semanticDeferred),
|
|
2348
|
-
};
|
|
2349
|
-
const semanticRefresh = await runProviderFirstDeferredSemanticRefresh({
|
|
2350
|
-
versionId,
|
|
2351
|
-
semanticDeferred: post.semanticDeferred,
|
|
2352
|
-
});
|
|
2353
|
-
providerFirstExecutedSummary = withProviderFirstPhaseTimings(providerFirstExecutedSummary);
|
|
2354
|
-
const result = {
|
|
2355
|
-
versionId,
|
|
2356
|
-
filesProcessed: materializedRows.files.length,
|
|
2357
|
-
changedFiles: materializedRows.changedFileIds.size,
|
|
2358
|
-
removedFiles: providerScan.removedFiles,
|
|
2359
|
-
symbolsIndexed: materializedRows.symbols.length +
|
|
2360
|
-
materializedRows.externalSymbols.length,
|
|
2361
|
-
edgesCreated: materializedRows.edges.length,
|
|
2362
|
-
clustersComputed: post.clustersComputed,
|
|
2363
|
-
processesTraced: post.processesTraced,
|
|
2364
|
-
durationMs: Date.now() - startTime,
|
|
2365
|
-
summaryStats: semanticRefresh.summaryStats ?? post.summaryStats,
|
|
2366
|
-
timings: phaseTimings
|
|
2367
|
-
? {
|
|
2368
|
-
totalMs: Date.now() - startTime,
|
|
2369
|
-
phases: phaseTimings,
|
|
2370
|
-
}
|
|
2371
|
-
: undefined,
|
|
2372
|
-
pass1Engine,
|
|
2373
|
-
scip,
|
|
2374
|
-
providerFirst,
|
|
2375
|
-
providerFirstExecution: providerFirstExecutedSummary,
|
|
2376
|
-
semanticDeferred: semanticRefresh.semanticDeferred,
|
|
2377
|
-
algorithmRefresh: post.algorithmRefresh,
|
|
2378
|
-
};
|
|
2379
|
-
return result;
|
|
2380
2328
|
}
|
|
2381
2329
|
}
|
|
2382
2330
|
}
|
|
2383
2331
|
}
|
|
2332
|
+
catch (err) {
|
|
2333
|
+
if (err instanceof ProviderFirstGraphValidationError)
|
|
2334
|
+
throw err;
|
|
2335
|
+
if (providerFirst.requestedMode !== "auto")
|
|
2336
|
+
throw err;
|
|
2337
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
2338
|
+
const fallbackReason = formatProviderFirstAutoFallbackReason({
|
|
2339
|
+
reason,
|
|
2340
|
+
providerFirstIncrementalActive,
|
|
2341
|
+
});
|
|
2342
|
+
logger.warn("indexRepo: provider-first phase failed (coverage scan or collection), using legacy fallback", { repoId, reason: fallbackReason });
|
|
2343
|
+
providerFirstExecutionFallback = providerFirstFallbackSummary([
|
|
2344
|
+
fallbackReason,
|
|
2345
|
+
]);
|
|
2346
|
+
// providerFirstScan stays undefined; legacy scanRepoForIndex will run below.
|
|
2347
|
+
}
|
|
2384
2348
|
}
|
|
2385
2349
|
const { files, existingByPath, removedFiles, removedFileIds, allFilesUnchanged: scanAllFilesUnchanged, } = providerFirstScan ??
|
|
2386
2350
|
(await measurePhase("scanRepo", () => scanRepoForIndex({
|
|
@@ -2963,6 +2927,11 @@ async function indexRepoImpl(repoId, mode, onProgress, signal, options, scipPreR
|
|
|
2963
2927
|
onProgress,
|
|
2964
2928
|
}));
|
|
2965
2929
|
recordFinalizeIndexingSubphaseTimings(finalizeResult.timings);
|
|
2930
|
+
await measurePhase("ensureCriticalSymbolFts", async () => {
|
|
2931
|
+
await ensureCriticalSymbolFtsIndex({
|
|
2932
|
+
recordTiming: recordIndexSubphaseTiming,
|
|
2933
|
+
});
|
|
2934
|
+
});
|
|
2966
2935
|
// Refresh read connection again after version/metrics writes.
|
|
2967
2936
|
freshConn = await getLadybugConn();
|
|
2968
2937
|
const derivedResult = providerFirstSkipDerivedStateReason
|