diff --git a/.github/standards/runner-policy/policy.json b/.github/standards/runner-policy/policy.json index 26c787c61..8892ef9d9 100644 --- a/.github/standards/runner-policy/policy.json +++ b/.github/standards/runner-policy/policy.json @@ -203,7 +203,7 @@ "issues": "write" } }, - "melodic-software/ci-workflows/.github/workflows/do-not-merge-gate.yml@885302176345486ca6c2c392d83131f9b5389251": { + "melodic-software/ci-workflows/.github/workflows/do-not-merge-gate.yml@90f1c54935203fa31b5b3d1f41531228be2c2b7f": { "routing": "runner-input", "runnerInput": "runner", "selectorResultInput": "prerequisite-result", @@ -308,7 +308,7 @@ "canonicalSelectorSecrets": { "observer-private-key": "${{ secrets.CI_RUNNER_OBSERVER_PRIVATE_KEY }}" }, - "approvedHostedRunnerLabels": ["ubuntu-24.04", "ubuntu-slim", "windows-2025"], + "approvedHostedRunnerLabels": ["ubuntu-24.04", "windows-2025"], "hostedMatrixExpressions": ["${{ matrix.os }}", "${{ matrix.runner }}"], "governedReusableRunnerInput": { "name": "runner", @@ -316,6 +316,7 @@ "default": "ubuntu-24.04", "failureSentinel": "ci-runner-selection-failed" }, + "fallbackLabelAllowlist": ["ubuntu-24.04"], "forbiddenHostedRunnerLabels": ["macos-latest", "ubuntu-latest", "windows-latest"], "managedLabelPatterns": [ "(?:^|[^a-z0-9-])(?:melodic|kyle)-(?:[a-z0-9]+-)*ubuntu-24\\.04-x64(?:-[a-z0-9-]+)?(?:$|[^a-z0-9-])" diff --git a/.github/standards/runner-policy/policy.schema.json b/.github/standards/runner-policy/policy.schema.json index 2d99b3b34..e42104483 100644 --- a/.github/standards/runner-policy/policy.schema.json +++ b/.github/standards/runner-policy/policy.schema.json @@ -16,6 +16,7 @@ "approvedHostedRunnerLabels", "hostedMatrixExpressions", "governedReusableRunnerInput", + "fallbackLabelAllowlist", "forbiddenHostedRunnerLabels", "managedLabelPatterns", "hostedExceptionReasons", @@ -72,6 +73,7 @@ "failureSentinel": { "const": "ci-runner-selection-failed" } } }, + "fallbackLabelAllowlist": { "$ref": "#/$defs/nonEmptyUniqueStringArray" }, "forbiddenHostedRunnerLabels": { "$ref": "#/$defs/nonEmptyUniqueStringArray" }, "managedLabelPatterns": { "$ref": "#/$defs/nonEmptyUniqueStringArray" }, "hostedExceptionReasons": { "$ref": "#/$defs/nonEmptyUniqueStringArray" }, diff --git a/.github/standards/runner-policy/runner-policy.mjs b/.github/standards/runner-policy/runner-policy.mjs index adcfd3a36..6a997639d 100755 --- a/.github/standards/runner-policy/runner-policy.mjs +++ b/.github/standards/runner-policy/runner-policy.mjs @@ -258,6 +258,11 @@ function validatePolicy(value) { "policy.governedReusableRunnerInput.default must be an approved hosted runner label", ); } + if (!new Set(value.fallbackLabelAllowlist).has(value.governedReusableRunnerInput.default)) { + throw new ConfigurationError( + "policy.governedReusableRunnerInput.default must be in policy.fallbackLabelAllowlist", + ); + } if ( approvedHostedRunnerLabels.has(value.governedReusableRunnerInput.failureSentinel) || forbiddenHostedRunnerLabels.has( diff --git a/REVIEW.md b/REVIEW.md index 1abcdd32a..2a820cf5f 100644 --- a/REVIEW.md +++ b/REVIEW.md @@ -65,6 +65,11 @@ criterion; a citation here never substitutes prose that isn't needed, per - A high-risk security action — authentication, an authorization failure, a privilege change, sensitive-data access — has a corresponding audit-log entry (`conventions/review/observability.md#logging`). +- A change that writes two or more related records, files, or state + locations carries an atomicity mechanism — a transaction, an atomic + rename, a constraint, or a compensation step — spanning them; an + interruption between steps must not leave state no code path expects + (`conventions/review/error-handling.md#atomicity`). ## Do not report