refactor(contracts): preserve named output schema types

Keep exact readonly schema maps and constrain contract factories to their owned keys. Verify named catalog lookups retain each schema type.
This commit is contained in:
morluto committed 2026-10-27 06:48:55 +08:00
1 parent 248133d784
commit b529bd84d7
11 files changed
+69 -32

No files matched your search

@@ -924,7 +924,7 @@ it("does not replay pre-envelope call graphs under the revised workflow profile"
}),
).toBeUndefined();
expect(
enhancedOutputSchemas.get_call_graph?.safeParse({
enhancedOutputSchemas.get_call_graph.safeParse({
normalized_result: oldResult,
}).success,
).toBe(false);
+2 -2
View File
@@ -1,3 +1,4 @@
import { requireOutputSchema } from "./toolOutputSchemaPrimitives.js";
import { z } from "zod";
import type { ToolContract } from "./toolContractTypes.js";
@@ -5,7 +6,6 @@ import { artifactOutputSchemas } from "./toolOutputSchemaGroups.js";
import { artifactIntegrityPolicySchema } from "../domain/artifactIntegrityPolicy.js";
import { jsonValueSchema } from "../domain/jsonValue.js";
import { toolContractMetadata } from "./toolEffects.js";
import { requireOutputSchema } from "./toolOutputSchemaPrimitives.js";
import { appleAssetCatalogInputSchema } from "../domain/apple/appleAssetCatalog.js";
import { dylibResolutionInputSchema } from "../domain/apple/dylibResolution.js";
import { keyedArchiveInputSchema } from "../domain/apple/keyedArchive.js";
@@ -52,7 +52,7 @@ const examples: Readonly<Record<string, Readonly<Record<string, unknown>>>> = {
};
const artifact = <
Name extends string,
Name extends keyof typeof artifactOutputSchemas,
Schema extends z.ZodType<Readonly<Record<string, unknown>>>,
>(
name: Name,
+5 -2
View File
@@ -1,15 +1,18 @@
import { requireOutputSchema } from "./toolOutputSchemaPrimitives.js";
import { analysisDetailSchema } from "./analysisDetail.js";
import { z } from "zod";
import { enhancedInputSchemas } from "./enhancedInputs.js";
import { enhancedOutputSchemas } from "./toolOutputSchemaGroups.js";
import { requireOutputSchema } from "./toolOutputSchemaPrimitives.js";
import { examplesFor } from "./toolContractHelpers.js";
import type { ToolContract } from "./toolContractTypes.js";
import { toolContractMetadata } from "./toolEffects.js";
import { FUNCTION_WORKFLOW_TOOL_CONTRACTS } from "./functionWorkflowToolContracts.js";
const enhanced = <Name extends string, Schema extends z.ZodObject>(
const enhanced = <
Name extends keyof typeof enhancedOutputSchemas,
Schema extends z.ZodObject,
>(
name: Name,
description: string,
inputSchema: Schema,
@@ -1,3 +1,4 @@
import { requireOutputSchema } from "./toolOutputSchemaPrimitives.js";
import { jsonObjectSchema } from "../domain/jsonValue.js";
import { analysisDetailSummaryDefaultSchema } from "./analysisDetail.js";
import { enhancedInputSchemas } from "./enhancedInputs.js";
@@ -5,7 +6,6 @@ import { TOOL_EXAMPLE_OVERRIDES } from "./toolContractExamples.js";
import type { ToolContract } from "./toolContractTypes.js";
import { toolContractMetadata } from "./toolEffects.js";
import { enhancedOutputSchemas } from "./toolOutputSchemaGroups.js";
import { requireOutputSchema } from "./toolOutputSchemaPrimitives.js";
type FunctionWorkflowName = "analyze_function" | "inspect_native_api";
@@ -1,9 +1,9 @@
import { requireOutputSchema } from "../toolOutputSchemaPrimitives.js";
import { z } from "zod";
import type { ToolContract } from "../toolContractTypes.js";
import { managedOutputSchemas } from "../toolOutputSchemaGroups.js";
import { toolContractMetadata } from "../toolEffects.js";
import { requireOutputSchema } from "../toolOutputSchemaPrimitives.js";
import { absoluteLocalPathStringSchema } from "../../domain/localPath.js";
import { analysisDetailSchema } from "../analysisDetail.js";
@@ -1,3 +1,4 @@
import { requireOutputSchema } from "../toolOutputSchemaPrimitives.js";
import { z } from "zod";
import { evidenceSchema } from "../../domain/evidence.js";
import { compareManagedMembersInputSchema } from "../../domain/managed/managedMemberComparison.js";
@@ -13,7 +14,6 @@ import {
MANAGED_RECONSTRUCTION_IMPORT_EXAMPLE,
} from "./managedWorkflowExamples.js";
import { toolContractMetadata } from "../toolEffects.js";
import { requireOutputSchema } from "../toolOutputSchemaPrimitives.js";
const managedApplicationGraphReferenceShape = z.strictObject({
managed_artifact: evidenceSchema.optional(),
+5 -2
View File
@@ -1,3 +1,4 @@
import { requireOutputSchema } from "../toolOutputSchemaPrimitives.js";
import { z } from "zod";
import { nativeCallObservationInputSchema } from "../../domain/native/nativeCallObservation.js";
import {
@@ -10,7 +11,6 @@ import { nativeOutputSchemas } from "../toolOutputSchemaGroups.js";
import { jsonValueSchema } from "../../domain/jsonValue.js";
import { localPathStringSchema } from "../../domain/localPath.js";
import { toolContractMetadata } from "../toolEffects.js";
import { requireOutputSchema } from "../toolOutputSchemaPrimitives.js";
import { analysisDetailSchema } from "../analysisDetail.js";
import { nativeCommandTimeoutField } from "../../domain/native/nativeDeadlines.js";
@@ -41,7 +41,10 @@ const examples: Readonly<Record<string, Readonly<Record<string, unknown>>>> = {
},
};
const native = <Name extends string, Schema extends z.ZodObject>(
const native = <
Name extends keyof typeof nativeOutputSchemas,
Schema extends z.ZodObject,
>(
name: Name,
description: string,
inputSchema: Schema,
+5 -2
View File
@@ -1,10 +1,10 @@
import { requireOutputSchema } from "./toolOutputSchemaPrimitives.js";
import { analysisDetailSchema } from "./analysisDetail.js";
import { z } from "zod";
import { jsonRecordSchema } from "../domain/jsonRecord.js";
import { nativeFunctionAnnotationsInputSchema } from "../domain/native/nativeFunctionAnnotations.js";
import { officialOutputSchemas } from "./toolOutputSchemaGroups.js";
import { requireOutputSchema } from "./toolOutputSchemaPrimitives.js";
import {
address,
document,
@@ -23,7 +23,10 @@ import { nativeSearchInput } from "../domain/native/nativeSearch.js";
const hopperRegexDeadline =
"Hopper regex mode uses ECMAScript Unicode syntax in a cancellable worker. The matching deadline is REA_REGEX_MATCHING_DEADLINE_MS (a positive decimal integer of milliseconds from 1 to 2147483647, default 5000). Unset keeps the default. A deadline failure names the effective milliseconds, source (default or setting), the default, and the maximum, and leaves the API usable. The worker old-generation request is REA_REGEX_WORKER_HEAP_REQUEST_MIB (a decimal integer of mebibytes from 7 to 16384, default 128). Unset keeps the default. A positive Node --max-old-space-size, including NODE_OPTIONS, overrides that request and is not limited by the setting's floor or maximum. A heap failure names the effective request, its source (default or setting), the default, the floor, and the maximum.";
const official = <Name extends string, Schema extends z.ZodObject>(
const official = <
Name extends keyof typeof officialOutputSchemas,
Schema extends z.ZodObject,
>(
name: Name,
description: string,
inputSchema: Schema,
+1 -1
View File
@@ -1,3 +1,4 @@
import { requireOutputSchema } from "./toolOutputSchemaPrimitives.js";
import { matchNativeFunctionsInputSchema } from "./native/functionMatchingContracts.js";
import { z } from "zod";
@@ -14,7 +15,6 @@ import {
import { reconstructionVerificationInputSchema } from "../domain/reconstructionVerificationSchemas.js";
import { staticRuntimeCorrelationInputSchema } from "../domain/staticRuntimeCorrelation.js";
import { sessionOutputSchemas } from "./toolOutputSchemaGroups.js";
import { requireOutputSchema } from "./toolOutputSchemaPrimitives.js";
import {
closeBinaryInputSchema,
openBundleResourcesInputSchema,
+30 -2
View File
@@ -1,4 +1,4 @@
import { describe, expect, it } from "vitest";
import { describe, expect, expectTypeOf, it } from "vitest";
import {
TOOL_FAMILY_DEFINITIONS,
@@ -6,7 +6,35 @@ import {
toolFamilyId,
} from "./toolFamilies.js";
import { TOOL_FAMILY_IDS } from "./toolFamilyIds.js";
import { TOOL_CONTRACTS } from "./toolContracts.js";
import { TOOL_CONTRACTS, toolContract } from "./toolContracts.js";
import type {
officialOutputSchemas,
enhancedOutputSchemas,
nativeOutputSchemas,
artifactOutputSchemas,
managedOutputSchemas,
managedWorkflowOutputSchemas,
} from "./toolOutputSchemaGroups.js";
// Catalog resolution must retain the exact schema owned by each named family.
expectTypeOf(
toolContract("inspect_native_instruction").outputSchema,
).toEqualTypeOf<typeof officialOutputSchemas.inspect_native_instruction>();
expectTypeOf(toolContract("analyze_function").outputSchema).toEqualTypeOf<
typeof enhancedOutputSchemas.analyze_function
>();
expectTypeOf(toolContract("inspect_macho").outputSchema).toEqualTypeOf<
typeof nativeOutputSchemas.inspect_macho
>();
expectTypeOf(toolContract("inspect_artifact").outputSchema).toEqualTypeOf<
typeof artifactOutputSchemas.inspect_artifact
>();
expectTypeOf(
toolContract("inspect_managed_artifact").outputSchema,
).toEqualTypeOf<typeof managedOutputSchemas.inspect_managed_artifact>();
expectTypeOf(
toolContract("compare_managed_members").outputSchema,
).toEqualTypeOf<typeof managedWorkflowOutputSchemas.compare_managed_members>();
describe("tool families", () => {
it("declares exactly one definition per published id", () => {
+17 -17
View File
@@ -25,13 +25,15 @@ import {
functionDossierSchema,
functionInstructionWindowSchema,
} from "../domain/native/functionDossier.js";
import { analysisBookmarkSchema } from "../domain/native/nativeInventory.js";
import {
analysisBookmarkSchema,
nativeInventoryRowsSchemas,
} from "../domain/native/nativeInventory.js";
import {
referenceEdgeSchema,
unresolvedCallSchema,
} from "../domain/native/nativeReference.js";
import { procedureIdentitySchema } from "../domain/native/procedureInfo.js";
import { nativeInventoryRowsSchemas } from "../domain/native/nativeInventory.js";
import { z } from "zod";
import { jsonRecordSchema } from "../domain/jsonRecord.js";
import { byteSearchResultSchema } from "../domain/native/bytePattern.js";
@@ -134,7 +136,7 @@ const bookmarkFacetSchema = z.discriminatedUnion("state", [
]);
/** Exact structured-content schemas shared by direct analysis providers. */
export const officialOutputSchemas: Readonly<Record<string, z.ZodObject>> = {
export const officialOutputSchemas = {
search_bytes: evidenceResultOf(byteSearchResultSchema),
annotate_native_function: evidenceResultOf(nativeFunctionAnnotationsSchema),
inspect_native_load_image: analysisDetailOutputSchemaOf(
@@ -252,7 +254,7 @@ export const officialOutputSchemas: Readonly<Record<string, z.ZodObject>> = {
set_inline_comment: evidenceResultOf(z.boolean()),
unset_bookmark: evidenceResultOf(z.boolean()),
xrefs: evidenceResultOf(nativeAddressListSchema),
};
} as const satisfies Readonly<Record<string, z.ZodObject>>;
const literalTraceOutput = evidenceResultOf(
z.object({
@@ -325,7 +327,7 @@ const batchProcedureIdentity = z.discriminatedUnion("status", [
]);
/** Exact structured-content schemas for composed analysis workflows. */
export const enhancedOutputSchemas: Readonly<Record<string, z.ZodObject>> = {
export const enhancedOutputSchemas = {
inspect_native_dispatch_metadata: evidenceResultOf(
nativeDispatchMetadataResultSchema,
),
@@ -432,7 +434,7 @@ export const enhancedOutputSchemas: Readonly<Record<string, z.ZodObject>> = {
inspect_native_api: evidenceResultOf(nativeApiInspectionResultSchema),
trace_feature: literalTraceOutput,
trace_call_path: callPathTraceOutput,
};
} as const satisfies Readonly<Record<string, z.ZodObject>>;
/** Complete entropy Evidence or its retained summary, shared by the named contract. */
export const byteEntropyOutputSchema = analysisDetailOutputSchemaOf(
@@ -441,7 +443,7 @@ export const byteEntropyOutputSchema = analysisDetailOutputSchemaOf(
);
/** Exact Evidence schemas for provider-neutral native inspection. */
export const nativeOutputSchemas: Readonly<Record<string, z.ZodObject>> = {
export const nativeOutputSchemas = {
inspect_byte_entropy: byteEntropyOutputSchema,
observe_native_ui: evidenceResultOf(nativeUiResultSchema),
capture_native_ui_scenario: evidenceResultOf(nativeUiResultSchema),
@@ -453,10 +455,10 @@ export const nativeOutputSchemas: Readonly<Record<string, z.ZodObject>> = {
inspect_plist: evidenceResultOf(inspectPlistSchema),
list_architectures: evidenceResultOf(listArchitecturesSchema),
demangle_swift: evidenceResultOf(demangleSwiftSchema),
};
} as const satisfies Readonly<Record<string, z.ZodObject>>;
/** Exact Evidence schemas for provider-neutral artifact graph operations. */
export const artifactOutputSchemas: Readonly<Record<string, z.ZodObject>> = {
export const artifactOutputSchemas = {
inspect_artifact: evidenceResultOf(
z.union([
artifactInspectionResultSchema,
@@ -473,10 +475,10 @@ export const artifactOutputSchemas: Readonly<Record<string, z.ZodObject>> = {
inspect_keyed_archive: evidenceResultOf(keyedArchiveResultSchema),
inspect_asset_catalog: evidenceResultOf(appleAssetCatalogResultSchema),
trace_dylib_resolution: evidenceResultOf(dylibResolutionResultSchema),
};
} as const satisfies Readonly<Record<string, z.ZodObject>>;
/** Exact Evidence schema for execution-free managed static analysis. */
export const managedOutputSchemas: Readonly<Record<string, z.ZodObject>> = {
export const managedOutputSchemas = {
inspect_managed_artifact: evidenceResultOf(
z.union([
managedArtifactInspectionSchema,
@@ -492,12 +494,10 @@ export const managedOutputSchemas: Readonly<Record<string, z.ZodObject>> = {
inspect_managed_native_boundaries: evidenceResultOf(
managedNativeBoundaryInspectionSchema,
),
};
} as const satisfies Readonly<Record<string, z.ZodObject>>;
/** Exact Evidence schema for provider-neutral managed workflows. */
export const managedWorkflowOutputSchemas: Readonly<
Record<string, z.ZodObject>
> = {
export const managedWorkflowOutputSchemas = {
compare_managed_members: evidenceResultOf(
managedMemberComparisonResultSchema,
),
@@ -510,7 +510,7 @@ export const managedWorkflowOutputSchemas: Readonly<
project_managed_application_graph: evidenceResultOf(
managedApplicationGraphResultSchema,
),
};
} as const satisfies Readonly<Record<string, z.ZodObject>>;
const lifecycleTargetFields = {
path: z.string(),
@@ -677,7 +677,7 @@ export const sessionOutputSchemas = {
unknown: residualUnknownSchema,
}),
),
} satisfies Readonly<Record<string, z.ZodObject>>;
} as const satisfies Readonly<Record<string, z.ZodObject>>;
/** Exact Evidence schema for read-only Electron fuse inspection. */
export const electronFuseOutputSchemas = {