From 6972d4c182237b9c6fd93cfc15bc52d4e606b53d Mon Sep 17 00:00:00 2001 From: Jinwoo-H Date: Sat, 12 Sep 2026 00:43:33 -0400 Subject: [PATCH] fix(relay): reuse canary across completed rollout batches --- ...cloud-deploy-relay-production-same-cap.yml | 2 +- .../relay-production-same-cap-wave.mjs | 9 +++-- .../relay-production-same-cap-wave.test.mjs | 37 ++++++++++++++++++- 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cloud-deploy-relay-production-same-cap.yml b/.github/workflows/cloud-deploy-relay-production-same-cap.yml index 50d609b30d3..31fe9bfb203 100644 --- a/.github/workflows/cloud-deploy-relay-production-same-cap.yml +++ b/.github/workflows/cloud-deploy-relay-production-same-cap.yml @@ -62,7 +62,7 @@ on: required: false type: string canary-run-id: - description: Successful same-commit canary run required for batch-apply + description: Successful same-code canary in this rehome control generation; reusable across batches required: false type: string confirmation: diff --git a/cloud/dev/scripts/relay-production-same-cap-wave.mjs b/cloud/dev/scripts/relay-production-same-cap-wave.mjs index 6e84c1c9104..8caa68e7ff2 100644 --- a/cloud/dev/scripts/relay-production-same-cap-wave.mjs +++ b/cloud/dev/scripts/relay-production-same-cap-wave.mjs @@ -87,18 +87,21 @@ export function canaryAuthority(input) { } export function verifyCanaryAuthority(authority, expected, repositoryRoot) { + const selectorGeneration = Number(expected.selectorGeneration) if ( authority?.v !== 1 || !/^[0-9a-f]{40}$/.test(authority.commitSha ?? '') || authority.runId !== expected.runId || authority.targetDigest !== expected.targetDigest || authority.rollbackDigest !== expected.rollbackDigest || - authority.selectorGeneration !== Number(expected.selectorGeneration) || + !Number.isSafeInteger(authority.selectorGeneration) || + authority.selectorGeneration < 0 || + !Number.isSafeInteger(selectorGeneration) || + selectorGeneration < authority.selectorGeneration || authority.rehomeGeneration !== Number(expected.rehomeGeneration) || !SAME_CAP_CELLS.includes(authority.cellId) ) throw new Error('canary authority does not match this batch') - // The batch dispatch resolves main after the canary sealed, so bind to the same code, not the - // same SHA; every field above still pins this batch to that exact canary. + // Each cell checks exact live selector state; later batches may reuse this control epoch's canary. requireSameEvidenceCode({ sealedSha: authority.commitSha, currentSha: expected.commitSha, diff --git a/cloud/dev/scripts/relay-production-same-cap-wave.test.mjs b/cloud/dev/scripts/relay-production-same-cap-wave.test.mjs index d636c324b33..7377f7a7af3 100644 --- a/cloud/dev/scripts/relay-production-same-cap-wave.test.mjs +++ b/cloud/dev/scripts/relay-production-same-cap-wave.test.mjs @@ -109,6 +109,41 @@ test('seals and verifies canary authority for later batches', () => { }), /does not match/) }) +test('reuses a canary across selector advances only within the same control epoch', () => { + const authority = canaryAuthority({ + cellIds: 'production-gce-c7', targetDigest, rollbackDigest, + confirmation: `ROLL_RELAY_SAME_CAP ${targetDigest} production-gce-c7`, + commitSha: 'c'.repeat(40), runId: '42', selectorGeneration: '11', rehomeGeneration: '4' + }) + const expected = { + commitSha: 'c'.repeat(40), runId: '42', targetDigest, rollbackDigest, + selectorGeneration: '21', rehomeGeneration: '4' + } + for (const generation of ['13', '14', '21', '29']) { + assert.equal(verifyCanaryAuthority(authority, { + ...expected, selectorGeneration: generation + }), authority) + } + for (const generation of ['12', '-1', 'NaN', 'Infinity', '13.5', '9007199254740992']) { + assert.throws(() => verifyCanaryAuthority(authority, { + ...expected, selectorGeneration: generation + }), /does not match/) + } + for (const generation of [-1, NaN, Infinity, 13.5, '13', Number.MAX_SAFE_INTEGER + 1]) { + assert.throws(() => verifyCanaryAuthority({ + ...authority, selectorGeneration: generation + }, expected), /does not match/) + } + for (const mismatch of [ + { rehomeGeneration: '3' }, { rehomeGeneration: '5' }, + { targetDigest: rollbackDigest }, { rollbackDigest: targetDigest }, { runId: '43' } + ]) { + assert.throws(() => verifyCanaryAuthority(authority, { + ...expected, ...mismatch + }), /does not match/) + } +}) + function gitIn(root, ...args) { return execFileSync('git', ['-C', root, ...args], { encoding: 'utf8' }).trim() } @@ -158,7 +193,7 @@ test('a batch trusts a canary sealed by identical code at an ancestor commit', a runId: '42', targetDigest, rollbackDigest, - selectorGeneration: '13', + selectorGeneration: '21', rehomeGeneration: '4' }, repositoryRoot) assert.equal(verifyAt(repository.sameCode, repository.root).cellId, 'production-gce-c7')