* fix(domain): preserve prototype-named JSON members through Evidence boundaries Zod's z.json() record projection drops own __proto__ members as a prototype-pollution guard, so provider replies carrying them lost evidence before hashing/serialization and CLI/MCP output. The shared schema now validates with z.json() as before, then rebuilds the value keeping prototype-named own members as ordinary data properties (__proto__ via Object.defineProperty, so the prototype is never mutated). parseHarJson no longer rejects __proto__ members; the explicit unsupported case from #992 is replaced with a preservation regression, and the inspect_web_network_capture contract text is updated to match. Fixes #1036 * fix(domain): bound JSON depth and oversized payloads at parsing boundaries jsonValueSchema re-walked hostile input through z.json()'s recursive core, so a deeply nested payload from an MCP tool argument, inline evidence, provider result, or keyed archive threw RangeError: Maximum call stack size exceeded instead of a validation issue. The schema now runs an iterative depth guard first and keeps z.json() for full JSON semantics behind it, which also turns cyclic values into validation errors. The 1000-edge limit stays far below the range where the recursive core overflows its stack (measured between 2000 and 3000 on Node 24) while leaving room for legitimately deep target-derived trees such as compiled NIB view hierarchies, and the guard narrows with a typed record check instead of any or unchecked casts. The non-recursive JSON Schema advertisement stays intact on both the public and standard projection paths. Two payload sizes get explicit budgets tied to their producer constraints: web text artifacts reject beyond the 16 MiB source budget the web tooling already advertises, and native UI screenshot base64 beyond the 64 MiB helper output budget. Regenerated product catalog, skill catalog digest, and completion-ledger manifest follow the schema-boundary change. * fix(validation): preserve depth diagnostics across process inputs --------- Co-authored-by: DeryFerd <deryferdikao125@gmail.com> Co-authored-by: N0zoM1z0 <1705004398@qq.com>
122 lines
3.8 KiB
TypeScript
122 lines
3.8 KiB
TypeScript
import { z } from "zod";
|
|
|
|
import {
|
|
JAVASCRIPT_SEMANTIC_NODE_KINDS,
|
|
JAVASCRIPT_SEMANTIC_RELATIONS,
|
|
javaScriptSemanticNodeSchema,
|
|
javaScriptSemanticRelationSchema,
|
|
javaScriptSemanticUnknownSchema,
|
|
} from "./javascriptSemanticGraphSchemas.js";
|
|
import { jsonValueSchema } from "../jsonValue.js";
|
|
import { digestSchema } from "../digests.js";
|
|
import { prefixedDigestSchema } from "../digests.js";
|
|
|
|
const semanticNodeIdSchema = prefixedDigestSchema("jsrg_node");
|
|
const literalValueSchema = jsonValueSchema.refine(
|
|
(value) =>
|
|
value === null ||
|
|
typeof value === "string" ||
|
|
typeof value === "number" ||
|
|
typeof value === "boolean",
|
|
"Literal seeds accept only JSON primitive values",
|
|
);
|
|
// Zod derivations drop the shared schema's JSON Schema projection override;
|
|
// re-apply it so MCP catalog generation keeps projecting `{}`.
|
|
literalValueSchema._zod.toJSONSchema = () => ({});
|
|
|
|
const literalSeedSchema = z.strictObject({
|
|
kind: z.literal("literal"),
|
|
value: literalValueSchema,
|
|
});
|
|
|
|
/** Authenticated starting points accepted by semantic tracing. */
|
|
export const javaScriptSemanticQuerySeedSchema = z.discriminatedUnion("kind", [
|
|
z.strictObject({
|
|
kind: z.literal("semantic-node"),
|
|
node_id: semanticNodeIdSchema,
|
|
}),
|
|
z.strictObject({
|
|
kind: z.literal("application-node"),
|
|
node_id: prefixedDigestSchema("jag_node"),
|
|
}),
|
|
literalSeedSchema,
|
|
z.strictObject({
|
|
kind: z.literal("function"),
|
|
fingerprint_sha256: digestSchema,
|
|
}),
|
|
z.strictObject({
|
|
kind: z.literal("property"),
|
|
name: z.string().min(1),
|
|
}),
|
|
z.strictObject({
|
|
kind: z.literal("endpoint"),
|
|
value: z.string().min(1),
|
|
}),
|
|
z.strictObject({
|
|
kind: z.literal("event"),
|
|
name: z.string().min(1),
|
|
}),
|
|
z.strictObject({
|
|
kind: z.literal("boundary-field"),
|
|
field: z.string().min(1),
|
|
}),
|
|
]);
|
|
|
|
/** Parsed pure-domain query over one authenticated companion graph. */
|
|
export const javaScriptSemanticQueryInputSchema = z.strictObject({
|
|
seed: javaScriptSemanticQuerySeedSchema,
|
|
direction: z.enum([
|
|
"backward-provenance",
|
|
"forward-influence",
|
|
"callers",
|
|
"ownership",
|
|
]),
|
|
allowed_relations: z
|
|
.array(z.enum(JAVASCRIPT_SEMANTIC_RELATIONS))
|
|
.min(1)
|
|
.optional(),
|
|
include_ambiguous_dynamic_edges: z.boolean().default(false),
|
|
expected: z
|
|
.strictObject({
|
|
role: z.enum(["source", "sink"]),
|
|
classes: z.array(z.enum(JAVASCRIPT_SEMANTIC_NODE_KINDS)).min(1),
|
|
})
|
|
.nullable()
|
|
.default(null),
|
|
});
|
|
|
|
/** Deterministic semantic trace result. */
|
|
export const javaScriptSemanticQueryResultSchema = z.strictObject({
|
|
query_id: prefixedDigestSchema("jsrq"),
|
|
source_graph_id: prefixedDigestSchema("jsrg"),
|
|
seed: javaScriptSemanticQuerySeedSchema,
|
|
direction: javaScriptSemanticQueryInputSchema.shape.direction,
|
|
status: z.enum(["found", "no-match", "ambiguous", "partial", "unsupported"]),
|
|
seed_node_ids: z.array(semanticNodeIdSchema),
|
|
nodes: z.array(javaScriptSemanticNodeSchema),
|
|
relations: z.array(javaScriptSemanticRelationSchema),
|
|
unknowns: z.array(javaScriptSemanticUnknownSchema),
|
|
expected_match_node_ids: z.array(semanticNodeIdSchema),
|
|
summary: z.strictObject({
|
|
total_seed_matches: z.number().int().min(0),
|
|
traversed_nodes: z.number().int().min(0),
|
|
traversed_relations: z.number().int().min(0),
|
|
traversed_functions: z.number().int().min(0),
|
|
traversed_modules: z.number().int().min(0),
|
|
relevant_unknowns: z.number().int().min(0),
|
|
}),
|
|
coverage: z.strictObject({
|
|
status: z.enum(["complete", "partial", "unavailable"]),
|
|
}),
|
|
limitations: z.array(z.string().min(1)),
|
|
});
|
|
|
|
/** Validated semantic query input. */
|
|
export type JavaScriptSemanticQueryInput = z.infer<
|
|
typeof javaScriptSemanticQueryInputSchema
|
|
>;
|
|
/** Validated semantic query result. */
|
|
export type JavaScriptSemanticQueryResult = z.infer<
|
|
typeof javaScriptSemanticQueryResultSchema
|
|
>;
|