fix: validate canonical Worker launch segments

This commit is contained in:
2026-09-03 14:43:53 +09:00
parent 1f32c693df
commit f3af8f21dc
2 changed files with 157 additions and 6 deletions
@@ -135,7 +135,10 @@ Deno.test("Worker create request parser requires the complete shared request", (
display_name: "Worker A", display_name: "Worker A",
profile: "builtin:coder", profile: "builtin:coder",
ticket_assignment: null, ticket_assignment: null,
initial_submit: [{ kind: "text", content: "Implement T-565." }], initial_submit: [
{ kind: "text", content: "Implement T-565." },
{ kind: "flow", selector: "builtin:coder-review" },
],
working_directory: { working_directory: {
working_directory_id: "workdir-a", working_directory_id: "workdir-a",
relative_cwd: null, relative_cwd: null,
@@ -159,4 +162,22 @@ Deno.test("Worker create request parser requires the complete shared request", (
Error, Error,
"initial_submit", "initial_submit",
); );
assertThrows(
() =>
parseCreateWorkspaceWorkerRequest({
...request,
initial_submit: [{ kind: "flow" }],
}),
Error,
"selector",
);
assertThrows(
() =>
parseCreateWorkspaceWorkerRequest({
...request,
initial_submit: [{ kind: "newer_client_segment" }],
}),
Error,
"kind is invalid",
);
}); });
+133 -3
View File
@@ -489,14 +489,144 @@ function ticketAssignment(
}; };
} }
function unsignedInteger(value: unknown, label: string): number {
const parsed = number(value, label);
if (!Number.isSafeInteger(parsed) || parsed < 0) {
throw new Error(`${label} must be a non-negative safe integer`);
}
return parsed;
}
function pasteArtifact(
value: unknown,
label: string,
): Extract<Segment, { kind: "paste_artifact" }>["artifact"] {
const item = record(value, label);
exact(
item,
[
"artifact_id",
"created_at_ms",
"media_type",
"availability",
"byte_len",
"char_count",
"line_count",
"sha256",
"source_entry_id",
],
label,
);
const mediaType = string(item.media_type, `${label}.media_type`);
if (mediaType !== "text_plain_utf8") {
throw new Error(`${label}.media_type is invalid`);
}
const availability = string(item.availability, `${label}.availability`);
if (
!["available", "unavailable", "integrity_failed"].includes(availability)
) {
throw new Error(`${label}.availability is invalid`);
}
return {
artifact_id: string(item.artifact_id, `${label}.artifact_id`),
created_at_ms: unsignedInteger(
item.created_at_ms,
`${label}.created_at_ms`,
),
media_type: mediaType,
availability: availability as Extract<Segment, { kind: "paste_artifact" }>[
"artifact"
]["availability"],
byte_len: unsignedInteger(item.byte_len, `${label}.byte_len`),
char_count: unsignedInteger(item.char_count, `${label}.char_count`),
line_count: unsignedInteger(item.line_count, `${label}.line_count`),
sha256: string(item.sha256, `${label}.sha256`),
source_entry_id: string(item.source_entry_id, `${label}.source_entry_id`),
};
}
function uploadedFile(
value: unknown,
label: string,
): Extract<Segment, { kind: "uploaded_file" }>["file"] {
const item = record(value, label);
exact(
item,
[
"artifact_id",
"file_name",
"media_type",
"created_at_ms",
"availability",
"byte_len",
"sha256",
"source_entry_id",
],
label,
);
const availability = string(item.availability, `${label}.availability`);
if (
!["available", "unavailable", "integrity_failed"].includes(availability)
) {
throw new Error(`${label}.availability is invalid`);
}
return {
artifact_id: string(item.artifact_id, `${label}.artifact_id`),
file_name: string(item.file_name, `${label}.file_name`),
media_type: string(item.media_type, `${label}.media_type`),
created_at_ms: unsignedInteger(
item.created_at_ms,
`${label}.created_at_ms`,
),
availability: availability as Extract<Segment, { kind: "uploaded_file" }>[
"file"
]["availability"],
byte_len: unsignedInteger(item.byte_len, `${label}.byte_len`),
sha256: string(item.sha256, `${label}.sha256`),
source_entry_id: optional(
item.source_entry_id,
`${label}.source_entry_id`,
string,
),
};
}
function segment(value: unknown, label: string): Segment { function segment(value: unknown, label: string): Segment {
const item = record(value, label); const item = record(value, label);
const kind = string(item.kind, `${label}.kind`); const kind = string(item.kind, `${label}.kind`) as Segment["kind"];
if (kind === "text") { switch (kind) {
case "text":
exact(item, ["kind", "content"], label); exact(item, ["kind", "content"], label);
return { kind, content: string(item.content, `${label}.content`) }; return { kind, content: string(item.content, `${label}.content`) };
} case "paste":
exact(item, ["kind", "id", "chars", "lines", "content"], label);
return {
kind,
id: unsignedInteger(item.id, `${label}.id`),
chars: unsignedInteger(item.chars, `${label}.chars`),
lines: unsignedInteger(item.lines, `${label}.lines`),
content: string(item.content, `${label}.content`),
};
case "paste_artifact":
exact(item, ["kind", "artifact"], label);
return {
kind,
artifact: pasteArtifact(item.artifact, `${label}.artifact`),
};
case "uploaded_file":
exact(item, ["kind", "file"], label);
return { kind, file: uploadedFile(item.file, `${label}.file`) };
case "file_ref":
exact(item, ["kind", "path"], label);
return { kind, path: string(item.path, `${label}.path`) };
case "flow":
exact(item, ["kind", "selector"], label);
return { kind, selector: string(item.selector, `${label}.selector`) };
case "unknown":
throw new Error(`${label}.kind is not supported by Worker creation`); throw new Error(`${label}.kind is not supported by Worker creation`);
}
const exhaustive: never = kind;
throw new Error(`${label}.kind is invalid: ${exhaustive}`);
} }
export function parseCreateWorkspaceWorkerRequest( export function parseCreateWorkspaceWorkerRequest(