Files
rea/src/application/OwnedJsonInput.ts
T
Edgar Arakelyan 7a0c47bfa4 feat(environment): export an environment manifest as an agent environment bundle (#4999)
Export an authenticated capture and environment manifest as a pinned agentenv bundle with provenance, a replay verifier and smoke task.

Followups preserve immutable input ownership, bounded discovery, caller paths and numeric values; bind bundle writes and package copying to retained filesystem owners; verify POSIX modes; retain cleanup authority; and verify framework/npm executable selection. Default MCP remains stdio.

Validation: pinned Linux toolchain, typecheck/build/lint/format/docs/knip, 452 focused tests, ten product-catalog cases, real GitHub response replay in the generated non-root Docker image, and the real pinned agentenv framework smoke workflow. Platform and resource-measurement limits are recorded in the feature verification document.

Co-authored-by: gensokyo-dev <gensokyo-dev@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-20 05:29:43 +08:00

55 lines
1.6 KiB
TypeScript

import { setImmediate } from "node:timers/promises";
import { AnalysisInputError } from "../domain/analysisErrorCore.js";
import { freezeOwnedJsonSnapshotSteps } from "../domain/immutableJson.js";
import {
jsonValueValidationSteps,
type JsonValue,
} from "../domain/jsonValue.js";
import { err, ok, type Result } from "../domain/result.js";
const finish = async <Value>(
steps: Generator<void, Value>,
signal?: AbortSignal,
): Promise<Value> => {
let completed = false;
try {
for (;;) {
signal?.throwIfAborted();
const step = steps.next();
if (step.done) {
completed = true;
return step.value;
}
await setImmediate(undefined, signal === undefined ? {} : { signal });
}
} finally {
// An abandoned validation/sealing traversal must release its provisional state.
if (!completed) steps.return(undefined as never);
}
};
/** Seal exclusively owned parser output so later schemas can share authenticated JSON subtrees. */
export const sealOwnedJsonInput = async (
value: unknown,
operation: string,
signal?: AbortSignal,
): Promise<Result<JsonValue, AnalysisInputError>> => {
const issue = await finish(jsonValueValidationSteps(value), signal);
if (issue !== undefined)
return err(
new AnalysisInputError(operation, { userMessage: issue }, [
{
path: [],
reason: "invalid_value",
expected: "bounded JSON-safe input",
message: issue,
},
]),
);
// The completed validator above established the JsonValue contract without a copy.
return ok(
await finish(freezeOwnedJsonSnapshotSteps(value as JsonValue), signal),
);
};