fix: keep valid older agent packages usable after desktop updates

Accept package-declared OpenCode, Node and koffi versions instead of desktop release pins. Preserve signature, hash, protocol and package-internal version consistency checks.

Validate both cached 0.11.18 packages and Linux x64 installation, bootstrap, health and stop. Related regression suite: 326 passed, 1 skipped; unrelated full-workspace check failures are recorded in the remote Host design.

Release note: Desktop updates no longer reject intact older Agent packages solely because their bundled runtime versions differ.
This commit is contained in:
mesalogo
2026-09-16 19:04:54 +08:00
parent 441f14b5f7
commit 1698d9fd3e
9 changed files with 100 additions and 24 deletions
@@ -66,6 +66,7 @@ export const TEST_REMOTE_RUNTIME_LOCK: RemoteRuntimeLock = {
export async function createRuntimeBundleTestFixture(
overrides: {
runtimeVersion?: RemoteRuntimeBundleManifest['runtimeVersion']
sourcePackage?: RemoteRuntimeBundleManifest['sourcePackage']
directoryDigest?: string
} = {}
@@ -87,7 +88,7 @@ export async function createRuntimeBundleTestFixture(
formatVersion: 2,
product: 'GoodBuddy',
runtimeId: 'opencode',
runtimeVersion: '1.18.29',
runtimeVersion: overrides.runtimeVersion ?? '1.18.29',
provider: 'opencode',
platform: 'linux',
architecture: 'x64',
@@ -127,7 +128,7 @@ export async function createRuntimeBundleTestFixture(
licenses: [
{
package: 'opencode-ai',
version: '1.18.29',
version: overrides.runtimeVersion ?? '1.18.29',
spdx: 'MIT',
path: 'licenses/opencode.txt'
}
@@ -31,14 +31,20 @@ afterEach(() => {
})
describe('Remote Runtime bundle verifier', () => {
it('verifies an authentic digest-addressed OpenCode bundle', async () => {
const fixture = await createBundle()
it.each(['1.18.29', '1.18.9'])('verifies an authentic digest-addressed OpenCode %s bundle with a matching lock', async (runtimeVersion) => {
const fixture = await createBundle({ runtimeVersion })
await expect(
verifyRuntimeBundle(fixture.bundleDirectory, {
architecture: 'x64',
releaseKeyRegistry: fixture.registry,
runtimeLock: lock,
runtimeLock: {
...lock,
runtimes: {
...lock.runtimes,
opencode: { ...lock.runtimes.opencode, version: runtimeVersion }
}
},
verificationEnvironment: 'test',
filesystemPlatform: 'win32'
})
@@ -108,14 +114,19 @@ describe('Remote Runtime bundle verifier', () => {
).rejects.toThrow(/payload (?:size|hash) mismatch/iu)
})
it('rejects a validly signed bundle outside the locked profile', async () => {
const fixture = await createBundle({
it.each([
{
runtimeVersion: '1.18.9'
},
{
sourcePackage: {
name: 'opencode-linux-x64',
integrity:
'sha512-VrvzV5Agrj0T2ZPvr5gzmh8xc4zqQ5pW8UeNgTzt5cJ/9Cbdxw6oFywgv7nfJqlpSfQqTWYJYH+LIHt3QdCS5g=='
}
})
}
])('rejects a validly signed bundle outside the locked profile: %j', async (overrides) => {
const fixture = await createBundle(overrides)
await expect(
verifyRuntimeBundle(fixture.bundleDirectory, {
@@ -259,6 +270,7 @@ describe('Remote Runtime bundle verifier', () => {
async function createBundle(
overrides: {
runtimeVersion?: RemoteRuntimeBundleManifest['runtimeVersion']
sourcePackage?: RemoteRuntimeBundleManifest['sourcePackage']
directoryDigest?: string
} = {}