refactor(javascript)!: remove obsolete scope truncation statistic

BREAKING CHANGE: remove the never-incremented truncated_scopes statistic from JavaScript application analysis results and schemas.
This commit is contained in:
morluto
2026-10-10 02:15:51 +08:00
parent b4a19193fe
commit 449d57075e
13 changed files with 7 additions and 38 deletions
@@ -47,7 +47,6 @@ interface MutableArtifactAnalysis<
findings: number;
modules: number;
parseFailures: number;
truncatedScopes: number;
}
interface ArtifactAnalysisContext<
@@ -132,7 +131,6 @@ const finalizeArtifactAnalysis = <
>(
state: MutableArtifactAnalysis<SemanticIr>,
): JavaScriptArtifactAnalysis<SemanticIr> => {
const truncatedScopes = state.truncatedScopes;
return {
files: state.files,
packages: state.packages,
@@ -143,13 +141,9 @@ const finalizeArtifactAnalysis = <
findings: state.findings + state.htmlScripts.length,
modules: state.modules,
parse_failures: state.parseFailures,
truncated_scopes: truncatedScopes,
limitations: [
"JavaScript and HTML were parsed as inert text; bundle bootstrap code was never executed.",
"Static paths and relationships may remain unresolved when expressions are dynamic or obfuscated.",
...(truncatedScopes === 0
? []
: ["Some static-analysis scopes were truncated."]),
],
};
};
@@ -222,7 +216,6 @@ const emptyArtifactAnalysis = <
findings: 0,
modules: 0,
parseFailures: 0,
truncatedScopes: 0,
});
const addStructuredObservations = (
@@ -123,7 +123,6 @@ export interface JavaScriptArtifactAnalysis<
readonly findings: number;
readonly modules: number;
readonly parse_failures: number;
readonly truncated_scopes: number;
readonly limitations: readonly string[];
}
@@ -132,8 +132,6 @@ const graphCoverage = (context: JavaScriptArtifactGraphContext) => {
sourceMapPolicyGap ||
malformedStructuredData ||
partialJavaScript;
if (context.analysis.truncated_scopes > 0)
return partialApplicationCoverage([], null);
if (resourceLimits.length > 0)
return partialApplicationCoverage(
semanticResourceLimitCoverage(resourceLimits),
@@ -49,7 +49,6 @@ export interface JavaScriptArtifactReconstructionResult {
readonly findings: number;
readonly modules: number;
readonly parse_failures: number;
readonly truncated_scopes: number;
};
readonly limitations: readonly string[];
}
@@ -129,7 +128,6 @@ export const reconstructJavaScriptArtifact = async (
const semanticGraphSteps = semanticProjection.finishImmutableSteps(
snapshot.manifest.root_sha256,
graph,
analysis,
);
await reportPhase(
"seal_javascript_semantic_graph",
@@ -162,7 +160,6 @@ export const reconstructJavaScriptArtifact = async (
findings: analysis.findings,
modules: analysis.modules,
parse_failures: analysis.parse_failures,
truncated_scopes: analysis.truncated_scopes,
},
limitations: analysis.limitations,
};
@@ -380,7 +380,6 @@ const graphFor = (source: string, ir = analyzeJavaScriptSemantics(source)) => {
findings: 0,
modules: 0,
parse_failures: 0,
truncated_scopes: 0,
limitations: [],
};
return buildJavaScriptSemanticGraph({
@@ -118,7 +118,7 @@ export const buildJavaScriptSemanticGraph = ({
if (analyzed.semantic !== null)
projection.projectFile(analyzed.file, analyzed.semantic.ir);
}
return projection.finish(rootArtifactSha256, applicationGraph, analysis);
return projection.finish(rootArtifactSha256, applicationGraph);
};
/** File-local semantic projection that does not retain consumed source IR. */
@@ -130,12 +130,10 @@ export interface JavaScriptSemanticGraphProjection {
readonly finish: (
rootArtifactSha256: string,
applicationGraph: BuilderInput["applicationGraph"],
analysis: Pick<JavaScriptArtifactAnalysis, "truncated_scopes">,
) => JavaScriptSemanticGraph;
readonly finishImmutableSteps: (
rootArtifactSha256: string,
applicationGraph: BuilderInput["applicationGraph"],
analysis: Pick<JavaScriptArtifactAnalysis, "truncated_scopes">,
) => Generator<void, JavaScriptSemanticGraph>;
}
@@ -171,7 +169,6 @@ export const createJavaScriptSemanticGraphProjection =
factory: (input: unknown) => Value,
rootArtifactSha256: string,
applicationGraph: BuilderInput["applicationGraph"],
analysis: Pick<JavaScriptArtifactAnalysis, "truncated_scopes">,
): Value => {
bindSemanticGraphApplicationNodes(state, applicationGraph);
if (state.roots.size === 0) addFallbackRoot(rootArtifactSha256, state);
@@ -202,7 +199,7 @@ export const createJavaScriptSemanticGraphProjection =
: [],
families: JAVASCRIPT_SEMANTIC_RELATION_FAMILIES.map((family) => ({
family,
status: semanticFamilyStatus(family, analysis),
status: semanticFamilyStatus(family),
retained_relations: [...state.relations.values()].filter(
(relation) =>
JAVASCRIPT_SEMANTIC_RELATION_FAMILY[relation.relation] ===
@@ -237,19 +234,17 @@ export const createJavaScriptSemanticGraphProjection =
};
return {
projectFile: projectSource,
finish: (rootArtifactSha256, applicationGraph, analysis) =>
finish: (rootArtifactSha256, applicationGraph) =>
finishWith(
createJavaScriptSemanticGraph,
rootArtifactSha256,
applicationGraph,
analysis,
),
finishImmutableSteps: (rootArtifactSha256, applicationGraph, analysis) =>
finishImmutableSteps: (rootArtifactSha256, applicationGraph) =>
finishWith(
createImmutableJavaScriptSemanticGraphSteps,
rootArtifactSha256,
applicationGraph,
analysis,
),
};
};
@@ -3,7 +3,6 @@ import type { JavaScriptSemanticGraphNode } from "../../domain/javascript/javasc
import { JAVASCRIPT_SEMANTIC_RELATION_FAMILIES } from "../../domain/javascript/javascriptSemanticGraphSchemas.js";
import type { JavaScriptSemanticIr } from "../../domain/javascript/javascriptSemanticIr.js";
import type { JavaScriptSourceRange } from "../../domain/javascript/javascriptStaticAnalysisTypes.js";
import type { JavaScriptArtifactAnalysis } from "./JavaScriptArtifactAnalysisTypes.js";
interface SourceInterval {
readonly range: JavaScriptSourceRange;
@@ -171,8 +170,7 @@ const rangeKey = (range: JavaScriptSourceRange): string =>
/** Report extractor support without treating missing families as absence. */
export const semanticFamilyStatus = (
family: (typeof JAVASCRIPT_SEMANTIC_RELATION_FAMILIES)[number],
analysis: Pick<JavaScriptArtifactAnalysis, "truncated_scopes">,
): "complete" | "partial" | "unknown" | "unsupported" => {
): "partial" | "unsupported" => {
if (
![
"call-flow",
@@ -190,7 +188,7 @@ export const semanticFamilyStatus = (
].includes(family)
)
return "unsupported";
return analysis.truncated_scopes === 0 ? "partial" : "unknown";
return "partial";
};
const contains = (
@@ -352,7 +352,6 @@ const emptyAnalysis = (): JavaScriptArtifactAnalysis => ({
findings: 0,
modules: 0,
parse_failures: 0,
truncated_scopes: 0,
limitations: [],
});
@@ -385,7 +384,6 @@ const graphFor = (source: string) => {
findings: 0,
modules: 0,
parse_failures: 0,
truncated_scopes: 0,
limitations: [],
};
return buildJavaScriptSemanticGraph({
@@ -36,7 +36,6 @@ const graphFor = (source: string) => {
findings: 0,
modules: 0,
parse_failures: 0,
truncated_scopes: 0,
limitations: [],
};
return buildJavaScriptSemanticGraph({
@@ -74,7 +74,6 @@ const statistics = {
findings: 1,
modules: 0,
parse_failures: 0,
truncated_scopes: 0,
};
const modulePath = "parser.mjs";
const limitations = [
@@ -164,7 +164,6 @@ export const JAVASCRIPT_APPLICATION_EVIDENCE_EXAMPLE = createEvidence(
findings: 0,
modules: 0,
parse_failures: 0,
truncated_scopes: 0,
},
limitations: [],
},
@@ -59,7 +59,6 @@ const reconstructionStatisticsSchema = z.strictObject({
findings: countSchema,
modules: countSchema,
parse_failures: countSchema,
truncated_scopes: countSchema,
});
const applicationAnalysisResultShape = z.strictObject({
@@ -70,11 +70,7 @@ it("preserves graph commitments and export shapes when consuming file-local IR",
expect(buildJavaScriptArtifactGraph(snapshot, files, compact)).toEqual(
graph,
);
const semantic = projection.finish(
snapshot.manifest.root_sha256,
graph,
compact,
);
const semantic = projection.finish(snapshot.manifest.root_sha256, graph);
expect(semantic).toEqual(
buildJavaScriptSemanticGraph({
rootArtifactSha256: snapshot.manifest.root_sha256,