From d369abd19ff063fd1d1e0af147464f50b92539f2 Mon Sep 17 00:00:00 2001 From: Dallin Romney Date: Sun, 13 Sep 2026 15:30:07 -0700 Subject: [PATCH] fix(setup): keep legacy fallback on exact stable release --- docs/SETUP_ENGINE_REDESIGN.md | 10 ++++++---- docs/adr/0001-gateway-release-policy.md | 12 +++++++----- src/OpenClaw.SetupEngine/GatewayInstallPolicy.cs | 5 ++--- .../GatewayInstallPolicyTests.cs | 2 +- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/docs/SETUP_ENGINE_REDESIGN.md b/docs/SETUP_ENGINE_REDESIGN.md index f3784d9d0..fd7dfc20c 100644 --- a/docs/SETUP_ENGINE_REDESIGN.md +++ b/docs/SETUP_ENGINE_REDESIGN.md @@ -375,10 +375,12 @@ Normal setup uses npm `latest`. `Gateway.Version` may select an upstream npm channel tag or an exact OpenClaw package version. `Gateway.FallbackVersion` may name an exact stable release to offer after a typed compatibility failure. Legacy `recommended`, `exact`, and `fallback` selections are migrated when the -configuration is loaded. Legacy recommendation and fallback configurations -without a recorded version follow the upstream `latest` and `extended-stable` -tags. Explicit legacy versions remain exact. Custom installers still require an -explicit exact version because they cannot resolve npm tags. The cross-repository +configuration is loaded. Legacy recommendation without a recorded version +follows the upstream `latest` tag. Legacy fallback without a recorded version +resolves to the pinned exact stable fallback `2026.9.4` instead of crossing to +`extended-stable`. Explicit legacy versions remain exact. Custom installers +still require an explicit exact version because they cannot resolve npm tags. +The cross-repository release gate may pass `--gateway-candidate-package ` with `--validate-gateway-candidate`, headless mode, and rollback-on-failure. The diff --git a/docs/adr/0001-gateway-release-policy.md b/docs/adr/0001-gateway-release-policy.md index fee4f36e6..5a24e1b80 100644 --- a/docs/adr/0001-gateway-release-policy.md +++ b/docs/adr/0001-gateway-release-policy.md @@ -33,11 +33,13 @@ evidence. - An operator may configure an exact stable `FallbackVersion`. Setup offers it only after a typed installed-version, protocol, or server-version failure. - Legacy `recommended`, `exact`, and `fallback` configurations are translated - into the new selector model. Legacy selections without a recorded version - follow the upstream `latest` recommendation or `extended-stable` fallback - tag. An explicitly recorded legacy version remains exact. Custom installers - still require an explicitly recorded exact version because they cannot resolve - npm tags. + into the new selector model. Legacy `recommended` without a recorded version + follows the upstream `latest` recommendation. Legacy `fallback` without a + recorded version resolves to the pinned exact stable fallback + `2026.9.4` instead of crossing to the mutable `extended-stable` channel. + An explicitly recorded legacy version remains exact. Custom installers still + require an explicitly recorded exact version because they cannot resolve npm + tags. - Embedded release evidence, the product security floor, and the candidate-promotion workflow are removed. - Setup continues to pin and verify Node `24.19.0`. This decision changes the diff --git a/src/OpenClaw.SetupEngine/GatewayInstallPolicy.cs b/src/OpenClaw.SetupEngine/GatewayInstallPolicy.cs index ea2fc92c5..3a6addd9a 100644 --- a/src/OpenClaw.SetupEngine/GatewayInstallPolicy.cs +++ b/src/OpenClaw.SetupEngine/GatewayInstallPolicy.cs @@ -148,8 +148,7 @@ public static class GatewayInstallPolicy public const int ProtocolGeneration = 4; public const string NodeVersion = "24.19.0"; public const string RecommendedTag = "latest"; - public const string FallbackTag = "extended-stable"; - + public const string LegacyFallbackVersion = "2026.9.4"; private static readonly HashSet s_supportedTags = new( ["latest", "next", "beta", "extended-stable", "dev"], StringComparer.OrdinalIgnoreCase); @@ -318,7 +317,7 @@ public static bool TryApplyFallback(SetupConfig config, out string? error) if (selection.Equals("fallback", StringComparison.OrdinalIgnoreCase)) { if (string.IsNullOrWhiteSpace(version)) - return FallbackTag; + return LegacyFallbackVersion; RequireExactVersion( version, diff --git a/tests/OpenClaw.SetupEngine.Tests/GatewayInstallPolicyTests.cs b/tests/OpenClaw.SetupEngine.Tests/GatewayInstallPolicyTests.cs index 39775ba01..f69912a9d 100644 --- a/tests/OpenClaw.SetupEngine.Tests/GatewayInstallPolicyTests.cs +++ b/tests/OpenClaw.SetupEngine.Tests/GatewayInstallPolicyTests.cs @@ -93,7 +93,7 @@ public void ValidateAndApply_RejectsUnknownOfficialSelector() [InlineData("""{"Gateway":{"Selection":"recommended","Version":"2026.6.34"}}""", "2026.6.34")] [InlineData("""{"Gateway":{"Selection":"exact","Version":"2026.6.34"}}""", "2026.6.34")] [InlineData("""{"Gateway":{"Version":"2026.6.34"}}""", "2026.6.34")] - [InlineData("""{"Gateway":{"Selection":"fallback"}}""", GatewayInstallPolicy.FallbackTag)] + [InlineData("""{"Gateway":{"Selection":"fallback"}}""", GatewayInstallPolicy.LegacyFallbackVersion)] [InlineData("""{"Gateway":{"Selection":"fallback","Version":"2026.6.11"}}""", "2026.6.11")] public void ValidateAndApply_MigratesLegacySelection( string json,