Merge master into canonical Runner D delivery

Resolve the migration sequence against current master while preserving the audited Runner D data migration. Type the native backend factory mock so the merged TypeScript checks retain its two-argument contract.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
Dev AgentandPaperclip committed 2026-08-19 21:17:29 +00:00
commit 83a1c438e0
227 files changed
+64329 -3014

No files matched your search

@@ -94,6 +94,12 @@ export const cancelEnvironmentCustomImageSetupSessionSchema = z.object({
export type CancelEnvironmentCustomImageSetupSession =
z.infer<typeof cancelEnvironmentCustomImageSetupSessionSchema>;
export const relinkEnvironmentCustomImageTemplateSchema = z.object({
confirmBootSourceDrift: z.boolean().optional().default(false),
}).strict();
export type RelinkEnvironmentCustomImageTemplate =
z.infer<typeof relinkEnvironmentCustomImageTemplateSchema>;
export const createEnvironmentCustomImageTerminalSessionTokenSchema = z.object({}).strict().default({});
export type CreateEnvironmentCustomImageTerminalSessionToken =
z.infer<typeof createEnvironmentCustomImageTerminalSessionTokenSchema>;
+2
View File
@@ -95,6 +95,7 @@ export {
startEnvironmentCustomImageSetupSessionSchema,
finishEnvironmentCustomImageSetupSessionSchema,
cancelEnvironmentCustomImageSetupSessionSchema,
relinkEnvironmentCustomImageTemplateSchema,
createEnvironmentCustomImageTerminalSessionTokenSchema,
environmentCustomImageTerminalSessionTokenSchema,
type EnvironmentCustomImageSetupConnectionSummary,
@@ -103,6 +104,7 @@ export {
type StartEnvironmentCustomImageSetupSession,
type FinishEnvironmentCustomImageSetupSession,
type CancelEnvironmentCustomImageSetupSession,
type RelinkEnvironmentCustomImageTemplate,
type CreateEnvironmentCustomImageTerminalSessionToken,
type EnvironmentCustomImageTerminalSessionToken,
} from "./environment-custom-images.js";
+84 -12
View File
@@ -313,18 +313,29 @@ describe("sandbox provider capability declaration validators", () => {
expect(rejected.success).toBe(false);
});
it("test_removed_concurrency_capabilities_are_rejected_as_unknown_keys", () => {
// The concurrency flags left the public contract because no runtime path
// enforced them. The strict schema now rejects them, so a manifest cannot
// declare a capability the host does not honor.
for (const key of ["concurrentSyncAndExec", "concurrentSyncOperations"]) {
const rejected = pluginManifestV1Schema.safeParse(
buildSandboxProviderManifest({
sandboxCapabilities: { [key]: true },
}),
);
expect(rejected.success).toBe(false);
}
it("test_manifest_accepts_concurrent_sync_operations_capability", () => {
// A provider opts in to parallel bidirectional file sync with this key. The
// strict schema accepts it and keeps the declared value.
const parsed = pluginManifestV1Schema.parse(
buildSandboxProviderManifest({
sandboxCapabilities: { concurrentSyncOperations: true },
}),
);
expect(parsed.environmentDrivers?.[0]?.sandboxCapabilities).toEqual({
concurrentSyncOperations: true,
});
});
it("test_manifest_rejects_unknown_sync_concurrency_capability_key", () => {
// A neighboring but unknown concurrency key must fail validation, not drop
// silently. The strict schema rejects a capability the host does not honor.
const rejected = pluginManifestV1Schema.safeParse(
buildSandboxProviderManifest({
sandboxCapabilities: { concurrentSyncAndExec: true },
}),
);
expect(rejected.success).toBe(false);
});
it("test_supports_reusable_leases_compat_maps_to_reusable_leases", () => {
@@ -350,3 +361,64 @@ describe("sandbox provider capability declaration validators", () => {
expect(resolveDeclaredSandboxCapabilities(driver!).reusableLeases).toBe(false);
});
});
describe("login pty transport capability and legacy alias", () => {
it("test_login_pty_new_field_parses_and_carries_the_flag", () => {
const parsed = pluginManifestV1Schema.parse(
buildSandboxProviderManifest({ supportsLoginPty: true }),
);
expect(parsed.environmentDrivers?.[0]?.supportsLoginPty).toBe(true);
});
it("test_legacy_alias_only_canonicalizes_onto_login_pty", () => {
const parsed = pluginManifestV1Schema.parse(
buildSandboxProviderManifest({ supportsSetupTokenLogin: true }),
);
const driver = parsed.environmentDrivers?.[0];
// The validator maps the deprecated alias onto the canonical field at parse
// time, and it drops the alias so a downstream reader cannot read the old
// name.
expect(driver?.supportsLoginPty).toBe(true);
expect(driver).not.toHaveProperty("supportsSetupTokenLogin");
});
it("test_conflicting_alias_and_new_field_reject", () => {
const rejected = pluginManifestV1Schema.safeParse(
buildSandboxProviderManifest({
supportsLoginPty: true,
supportsSetupTokenLogin: false,
}),
);
expect(rejected.success).toBe(false);
});
it("test_matching_alias_and_new_field_pass", () => {
const parsed = pluginManifestV1Schema.parse(
buildSandboxProviderManifest({
supportsLoginPty: true,
supportsSetupTokenLogin: true,
}),
);
expect(parsed.environmentDrivers?.[0]?.supportsLoginPty).toBe(true);
});
it("test_unknown_login_field_misspelling_rejects", () => {
const rejected = pluginManifestV1Schema.safeParse(
buildSandboxProviderManifest({ supportsLoginPTY: true }),
);
expect(rejected.success).toBe(false);
});
it("test_login_pty_accepts_literal_booleans_only", () => {
const rejected = pluginManifestV1Schema.safeParse(
buildSandboxProviderManifest({ supportsLoginPty: "true" }),
);
expect(rejected.success).toBe(false);
});
});
+37 -2
View File
@@ -157,8 +157,8 @@ export const pluginEnvironmentTemplateConfigBindingSchema = z.object({
// The nested sandbox capability declaration is `.strict()` so an unknown
// capability key is a validation error, not a silently dropped field. The outer
// driver schema below is non-strict and drops unknown top-level keys, so the
// declaration itself is the gate that a typo in a capability name cannot pass.
// driver schema below is also `.strict()`, so a typo in a top-level capability
// name cannot pass either.
export const sandboxProviderCapabilitiesSchema = z.object({
reusableLeases: z.boolean().optional(),
nativeSyncIn: z.boolean().optional(),
@@ -166,10 +166,15 @@ export const sandboxProviderCapabilitiesSchema = z.object({
persistentProcessSessions: z.boolean().optional(),
independentControlCommands: z.boolean().optional(),
incrementalSessionOutput: z.boolean().optional(),
concurrentSyncOperations: z.boolean().optional(),
duplexCommandStream: z.boolean().optional(),
}).strict();
export type SandboxProviderCapabilitiesInput = z.infer<typeof sandboxProviderCapabilitiesSchema>;
// The driver declaration schema is `.strict()` so an unknown top-level key is a
// validation error, not a silently dropped field. A misspelled capability name
// (for example `supportsLoginPTY`) fails validation instead of dropping.
export const pluginEnvironmentDriverDeclarationSchema = z.object({
driverKey: z.string().min(1).regex(
/^[a-z0-9][a-z0-9._-]*$/,
@@ -187,8 +192,38 @@ export const pluginEnvironmentDriverDeclarationSchema = z.object({
templateConfigBinding: pluginEnvironmentTemplateConfigBindingSchema.optional(),
templateIdentityPaths: z.array(z.string().min(1).max(200)).max(20).optional(),
supportsTemplateDelete: z.boolean().optional(),
// The neutral transport capability: does the provider host an interactive
// login on a real pseudo-terminal? Validate a literal boolean only.
supportsLoginPty: z.boolean().optional(),
// Deprecated alias for `supportsLoginPty`. It exists only so an external
// plugin manifest that declares the old name still loads. Validate a literal
// boolean only. The transform below canonicalizes it onto `supportsLoginPty`
// and drops it, so every downstream reader reads only the canonical field.
supportsSetupTokenLogin: z.boolean().optional(),
configSchema: jsonSchemaSchema,
}).strict().superRefine((driver, ctx) => {
// Reject a manifest that carries both the alias and the canonical field with
// different values. Matching values pass. A single field passes.
if (
driver.supportsLoginPty !== undefined
&& driver.supportsSetupTokenLogin !== undefined
&& driver.supportsLoginPty !== driver.supportsSetupTokenLogin
) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message:
"supportsSetupTokenLogin is a deprecated alias for supportsLoginPty; the two flags must not carry different values",
path: ["supportsLoginPty"],
});
}
}).transform((driver) => {
// Canonicalize before any authorization or projection reads the value. The
// canonical field wins; the alias fills it in when only the alias is present.
// Drop the alias so every downstream reader reads only `supportsLoginPty`. An
// undefined value is omitted on JSON serialization, so a driver that declares
// neither field carries no login flag.
const { supportsSetupTokenLogin, ...rest } = driver;
return { ...rest, supportsLoginPty: rest.supportsLoginPty ?? supportsSetupTokenLogin };
});
export type PluginEnvironmentDriverDeclarationInput = z.infer<