Problem
In #288, prepareCodeEnvironment computes the portable snapshot key before waiting on withDependencySnapshot's per-key lock. After acquiring the lock, prepareInLock computes a fresh checkout-local receipt key but continues restoring or publishing under the original portable key.
If declared reuse inputs change while another checkout holds the lock, a snapshot for the old inputs can be restored and accepted under a receipt for the new inputs. A readiness command that only checks artifact existence can pass. The post-restore key comparison only verifies the new local key, not the portable key used to choose the snapshot. The setup path can likewise publish dependencies for the new inputs under the old portable key.
Recompute the portable key after acquiring the lock, reject/retry when it changed, and ensure the restored or published snapshot always corresponds to the same inputs checked by readiness.
Add a regression that holds key A's lock, starts another preparation, changes its lockfile to B while it waits, and then releases A. Neither restoring A for B nor publishing B under A should succeed.
Inherited Bugbot finding: https://github.com/ClickHouse/ai/pull/4172#discussion_r4165537171
Affected code: packages/code/src/environment-preparation.ts.
Problem
In #288,
prepareCodeEnvironmentcomputes the portable snapshot key before waiting onwithDependencySnapshot's per-key lock. After acquiring the lock,prepareInLockcomputes a fresh checkout-local receipt key but continues restoring or publishing under the original portable key.If declared reuse inputs change while another checkout holds the lock, a snapshot for the old inputs can be restored and accepted under a receipt for the new inputs. A readiness command that only checks artifact existence can pass. The post-restore key comparison only verifies the new local key, not the portable key used to choose the snapshot. The setup path can likewise publish dependencies for the new inputs under the old portable key.
Recompute the portable key after acquiring the lock, reject/retry when it changed, and ensure the restored or published snapshot always corresponds to the same inputs checked by readiness.
Add a regression that holds key A's lock, starts another preparation, changes its lockfile to B while it waits, and then releases A. Neither restoring A for B nor publishing B under A should succeed.
Inherited Bugbot finding: https://github.com/ClickHouse/ai/pull/4172#discussion_r4165537171
Affected code:
packages/code/src/environment-preparation.ts.