fix(javascript): bound semantic unknown retention at projection

Admit unknowns before canonical construction and provenance interning. Offer independent per-file and application capacities through CLI, Evidence and the owned analysis worker, and reject over-allocation during streamed decoding.

Report examined omitted emission occurrences by family and reason without retaining discarded identities. Preserve omission-free graph identities and distinguish node truncation from overall partial coverage.

Fixes #4797
This commit is contained in:
morluto
2026-10-17 21:57:31 +08:00
parent 926e18b3fc
commit f4322b15ed
34 changed files with 892 additions and 293 deletions
@@ -271,6 +271,24 @@ export const JAVASCRIPT_SEMANTIC_UNKNOWN_REASONS = [
"unsupported-syntax",
] as const;
/** Counts examined emission occurrences, including repeats, without retaining discarded IDs. */
export const javaScriptSemanticUnknownOmissionSchema = z.strictObject({
family: z.enum(JAVASCRIPT_SEMANTIC_RELATION_FAMILIES),
reason: z.enum(JAVASCRIPT_SEMANTIC_UNKNOWN_REASONS),
occurrences: z.number().int().positive(),
});
/** At most one summary row for each finite family/reason pair. */
export const javaScriptSemanticUnknownOmissionsSchema = z
.array(javaScriptSemanticUnknownOmissionSchema)
.min(1)
.max(
JAVASCRIPT_SEMANTIC_RELATION_FAMILIES.length *
JAVASCRIPT_SEMANTIC_UNKNOWN_REASONS.length,
);
export type JavaScriptSemanticUnknownOmission = z.infer<
typeof javaScriptSemanticUnknownOmissionSchema
>;
/** One unresolved semantic frontier before its ID is derived. */
export const javaScriptSemanticUnknownInputSchema = z.strictObject({
node_id: semanticNodeIdSchema.nullable(),
@@ -337,6 +355,8 @@ const familyCoverageSchema = z.strictObject({
const graphCoverageSchema = z.strictObject({
status: z.enum(["complete", "partial", "unknown", "unavailable"]),
truncated: z.boolean(),
omitted_unknown_occurrences:
javaScriptSemanticUnknownOmissionsSchema.exactOptional(),
omitted_nodes: z.number().int().min(0).nullable(),
omitted_relations: z.number().int().min(0).nullable(),
limits: z.array(