From 6177286ae7296dd9d51027e842eb0dcb3c633da7 Mon Sep 17 00:00:00 2001 From: ematipico Date: Tue, 15 Sep 2026 14:40:07 +0100 Subject: [PATCH] fix: sandbox id --- src/adversary/contracts.ts | 13 +++++++++++++ src/adversary/workflow.ts | 8 +------- tests/adversary-contracts.test.ts | 15 +++++++++++++++ 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/adversary/contracts.ts b/src/adversary/contracts.ts index df2cd2b..4dfc4b0 100644 --- a/src/adversary/contracts.ts +++ b/src/adversary/contracts.ts @@ -119,6 +119,19 @@ export function adversaryCoordinatorKey( return `${input.repositoryId}:${input.pullNumber}`; } +export function adversarySandboxId( + team: 'blue' | 'purple' | 'publisher', + input: Pick< + AdversaryWorkflowParams, + 'repositoryId' | 'pullNumber' | 'deliveryId' + >, +): string { + const delivery = input.deliveryId.toLowerCase().replace(/[^a-z0-9-]/g, '-'); + return `adversary-${team}-${input.repositoryId}-${input.pullNumber}-${delivery}` + .slice(0, 63) + .replace(/-+$/, ''); +} + export function blueQualifies(result: PurpleTeamResult): boolean { return Object.values(result.qualification).every(Boolean); } diff --git a/src/adversary/workflow.ts b/src/adversary/workflow.ts index 02a09c5..d8fface 100644 --- a/src/adversary/workflow.ts +++ b/src/adversary/workflow.ts @@ -29,6 +29,7 @@ import { type AdversaryWorkflowOutcome, type AdversaryWorkflowParams, adversaryCoordinatorKey, + adversarySandboxId, adversaryWorkflowParamsSchema, type BlueTeamInput, type BlueTeamResult, @@ -421,13 +422,6 @@ export class AdversaryWorkflow extends WorkflowEntrypoint< } } -function adversarySandboxId( - team: 'blue' | 'purple' | 'publisher', - params: AdversaryWorkflowParams, -): string { - return `adversary-${team}-${params.repositoryId}-${params.pullNumber}-${params.deliveryId}`; -} - async function destroyInStep( step: WorkflowStep, team: string, diff --git a/tests/adversary-contracts.test.ts b/tests/adversary-contracts.test.ts index e8174ce..7fe58a9 100644 --- a/tests/adversary-contracts.test.ts +++ b/tests/adversary-contracts.test.ts @@ -1,6 +1,7 @@ import { describe, expect, it } from 'vitest'; import { adversaryBranchName, + adversarySandboxId, blueQualifies, type PurpleTeamResult, } from '../src/adversary/contracts.ts'; @@ -41,4 +42,18 @@ describe('adversary contracts', () => { 'factory/adversary/pr-42-aaaaaaaaaaaa', ); }); + + it('builds bounded DNS-label-safe sandbox ids', () => { + const input = { + repositoryId: 348060227, + pullNumber: 17736, + deliveryId: '560CE130_B10A 11F1/862F/F478BF7BDFDE', + }; + + for (const team of ['blue', 'purple', 'publisher'] as const) { + const id = adversarySandboxId(team, input); + expect(id.length).toBeLessThanOrEqual(63); + expect(id).toMatch(/^[a-z0-9][a-z0-9-]*[a-z0-9]$/); + } + }); });