refactor: centralize input validation and schema interpretation

Migrate twelve application service files to the existing provider input owner,
preserving schema causes, cancellation precedence, caller selection, and
retained Evidence. Keep flows with distinct error policies separate.

Replace the DeepSeek verifier's recursive object scan with schema-position
traversal using the canonical keyword and local-reference owners. Literal
pattern fields no longer cause false regex failures; patternProperties keys
are checked alongside actual pattern constraints in native regex modes.

Validation: 271 focused workflow/service tests and six verifier regressions
passed; static checks, discovery, and actual Node source-loader smoke passed.
The baseline scanner reproduced the new regressions. Installed DeepSeek client
execution was not run.
This commit is contained in:
morluto
2026-10-26 17:05:05 +08:00
parent 8a65787507
commit 6c35d74a7d
15 changed files with 324 additions and 240 deletions
+14 -18
View File
@@ -1,3 +1,4 @@
import { parseProviderOperationInput } from "../ProviderOperationExecution.js";
import { analysisErrorWithCleanupFailure } from "../../domain/analysisErrorCleanup.js";
import { ProviderCleanupError } from "../../domain/providerCleanupError.js";
import type {
@@ -25,7 +26,6 @@ import {
type Il2cppMetadata,
type Il2cppMetadataProviderInput,
} from "../../domain/il2cpp/il2cppMetadata.js";
import { analysisInputErrorFromIssues } from "../../domain/inputIssueProjection.js";
import { err, ok, type Result } from "../../domain/result.js";
const OPERATION = "inspect_il2cpp_metadata";
@@ -99,20 +99,16 @@ export class Il2cppMetadataService {
retention: AnalysisViewRetention,
output?: Il2cppSeedOutput,
): Promise<Result<Evidence, AnalysisError>> {
if (options?.signal?.aborted)
return err(
new AnalysisCancelledError(OPERATION, { cause: options.signal.reason }),
);
const input = inspectIl2cppMetadataInputSchema.safeParse(rawInput);
if (!input.success)
return err(
analysisInputErrorFromIssues(OPERATION, input.error.issues, rawInput, {
cause: input.error,
}),
);
const input = parseProviderOperationInput(
OPERATION,
rawInput,
inspectIl2cppMetadataInputSchema,
options?.signal,
);
if (!input.ok) return input;
if (
input.data.binary_architecture !== undefined &&
input.data.binary_path === undefined
input.value.binary_architecture !== undefined &&
input.value.binary_path === undefined
)
return err(
new AnalysisInputError(OPERATION, undefined, [
@@ -124,8 +120,8 @@ export class Il2cppMetadataService {
]),
);
if (
input.data.generic_instances === true &&
input.data.binary_path === undefined
input.value.generic_instances === true &&
input.value.binary_path === undefined
)
return err(
new AnalysisInputError(OPERATION, undefined, [
@@ -137,7 +133,7 @@ export class Il2cppMetadataService {
]),
);
if (output !== undefined) {
if (input.data.binary_path === undefined)
if (input.value.binary_path === undefined)
return err(
new AnalysisInputError(OPERATION, undefined, [
{
@@ -158,7 +154,7 @@ export class Il2cppMetadataService {
const ready = await this.seeds.check(output, options);
if (!ready.ok) return ready;
}
const { detail, ...providerInput } = input.data;
const { detail, ...providerInput } = input.value;
if (detail === "summary") {
const ready = requireAnalysisViewRetention(OPERATION, retention);
if (!ready.ok) return ready;