feat(cloud): default distributed plans to v2 (#3311)

* feat(cloud): default distributed plans to v2

* fix(cloud): address plan v2 review feedback

* fix(examples): document explicit v2 samples
This commit is contained in:
James Russo
2026-08-17 17:24:31 -04:00
committed by GitHub
parent 6b17c24f98
commit 17a2a00ed5
36 changed files with 403 additions and 143 deletions
+61 -5
View File
@@ -145,6 +145,7 @@ describe("unwrapEvent", () => {
it("unwraps a Step Functions { Payload } envelope", () => {
const inner: RenderChunkEvent = {
Action: "renderChunk",
PlanProtocol: "v1",
PlanS3Uri: "s3://bucket/plan.tar.gz",
PlanHash: "deadbeef",
ChunkIndex: 3,
@@ -158,6 +159,7 @@ describe("unwrapEvent", () => {
it("unwraps multiple levels of envelopes", () => {
const inner: AssembleEvent = {
Action: "assemble",
PlanProtocol: "v1",
PlanS3Uri: "s3://bucket/plan.tar.gz",
ChunkS3Uris: ["s3://bucket/chunks/0001.mp4"],
AudioS3Uri: null,
@@ -176,7 +178,7 @@ describe("unwrapEvent", () => {
});
describe("handler dispatch", () => {
it("routes Action='plan' to the plan primitive", async () => {
it("preserves explicit v1 plan compatibility", async () => {
const tmpRoot = makeTmpRoot();
const s3 = new FakeS3Client();
// Seed a fake project tarball so the untar step has something to chew on.
@@ -213,6 +215,7 @@ describe("handler dispatch", () => {
const event: PlanEvent = {
Action: "plan",
PlanProtocol: "v1",
ProjectS3Uri: "s3://bucket/project.tar.gz",
PlanOutputS3Prefix: "s3://bucket/renders/abc/",
Config: { fps: 30, width: 1920, height: 1080, format: "mp4" },
@@ -270,6 +273,7 @@ describe("handler dispatch", () => {
handler(
{
Action: "plan",
PlanProtocol: "v1",
ProjectS3Uri: "s3://bucket/project.tar.gz",
PlanOutputS3Prefix: "s3://bucket/renders/terminal/",
Config: { fps: 30, width: 640, height: 360, format: "mp4" },
@@ -332,6 +336,7 @@ describe("handler dispatch", () => {
const event: PlanEvent = {
Action: "plan",
PlanProtocol: "v1",
ProjectS3Uri: "s3://bucket/project.tar.gz",
PlanOutputS3Prefix: "s3://bucket/renders/abc/",
Config: { fps: 30, width: 1920, height: 1080, format: "mp4" },
@@ -406,6 +411,7 @@ describe("handler dispatch", () => {
const event: RenderChunkEvent = {
Action: "renderChunk",
PlanProtocol: "v1",
PlanS3Uri: "s3://bucket/plan.tar.gz",
PlanHash: "fakehash",
ChunkIndex: 2,
@@ -455,6 +461,7 @@ describe("handler dispatch", () => {
const event: RenderChunkEvent = {
Action: "renderChunk",
PlanProtocol: "v1",
PlanS3Uri: "s3://bucket/plan.tar.gz",
PlanHash: "not-the-real-hash",
ChunkIndex: 0,
@@ -511,6 +518,7 @@ describe("handler dispatch", () => {
const event: AssembleEvent = {
Action: "assemble",
PlanProtocol: "v1",
PlanS3Uri: "s3://bucket/plan.tar.gz",
ChunkS3Uris: ["s3://bucket/chunks/0001.mp4", "s3://bucket/chunks/0002.mp4"],
AudioS3Uri: null,
@@ -541,7 +549,7 @@ describe("handler dispatch", () => {
expect(assembleMock).toHaveBeenCalledTimes(1);
});
it("runs v2 plan → target-scoped chunk → assemble without a PlanS3Uri", async () => {
it("defaults omitted plan protocol to v2 across plan → chunk → assemble", async () => {
const tmpRoot = makeTmpRoot();
const s3 = new FakeS3Client();
s3.objects.set("s3://bucket/project.tar.gz", await makeMinimalProjectTar());
@@ -614,7 +622,6 @@ describe("handler dispatch", () => {
const planned = await handler(
{
Action: "plan",
PlanProtocol: "v2",
ProjectS3Uri: "s3://bucket/project.tar.gz",
PlanOutputS3Prefix: "s3://bucket/renders/v2/",
Config: { fps: 30, width: 640, height: 360, format: "mp4" },
@@ -642,7 +649,6 @@ describe("handler dispatch", () => {
const chunk = await handler(
{
Action: "renderChunk",
PlanProtocol: "v2",
PlanV2ManifestS3Uri: planned.PlanV2ManifestS3Uri,
PlanV2ArtifactS3Prefix: planned.PlanV2ArtifactS3Prefix,
PlanHash: planned.PlanHash,
@@ -661,7 +667,6 @@ describe("handler dispatch", () => {
await handler(
{
Action: "assemble",
PlanProtocol: "v2",
PlanV2ManifestS3Uri: planned.PlanV2ManifestS3Uri,
PlanV2ArtifactS3Prefix: planned.PlanV2ArtifactS3Prefix,
PlanHash: planned.PlanHash,
@@ -677,6 +682,56 @@ describe("handler dispatch", () => {
).toBe(true);
});
it("rejects unknown plan protocol values", async () => {
const tmpRoot = makeTmpRoot();
const s3 = new FakeS3Client();
await expect(
handler(
{
Action: "plan",
PlanProtocol: "v3",
ProjectS3Uri: "s3://bucket/project.tar.gz",
PlanOutputS3Prefix: "s3://bucket/renders/invalid/",
Config: { fps: 30, width: 640, height: 360, format: "mp4" },
} as unknown as LambdaEvent,
{
s3: s3 as unknown as import("@aws-sdk/client-s3").S3Client,
tmpRoot,
skipChromeResolution: true,
},
),
).rejects.toMatchObject({ name: "PLAN_PROTOCOL_UNSUPPORTED" });
expect(s3.ops).toHaveLength(0);
});
it("rejects mixed v1/v2 plan locators at runtime", async () => {
const tmpRoot = makeTmpRoot();
const s3 = new FakeS3Client();
await expect(
handler(
{
Action: "renderChunk",
PlanS3Uri: "s3://bucket/plan.tar.gz",
PlanHash: "fakehash",
ChunkIndex: 0,
ChunkOutputS3Prefix: "s3://bucket/renders/mixed/",
Format: "mp4",
} as unknown as LambdaEvent,
{
s3: s3 as unknown as import("@aws-sdk/client-s3").S3Client,
tmpRoot,
skipChromeResolution: true,
},
),
).rejects.toMatchObject({
name: "PLAN_PROTOCOL_UNSUPPORTED",
message: expect.stringContaining("mixed or missing plan locators"),
});
expect(s3.ops).toHaveLength(0);
});
it("rejects unknown actions", async () => {
const tmpRoot = makeTmpRoot();
await expect(
@@ -735,6 +790,7 @@ describe("handler — S3 URI allowlist (security: F-004)", () => {
const event: AssembleEvent = {
Action: "assemble",
PlanProtocol: "v1",
PlanS3Uri: "s3://good-bucket/plan.tar.gz",
ChunkS3Uris: ["s3://good-bucket/chunks/0001.mp4", "s3://evil-bucket/chunks/0002.mp4"],
AudioS3Uri: null,