New image patch ci/images/paperclip/ren-841-k8s-termination-receipt.patch for @paperclipai/plugin-kubernetes:
onEnvironmentReleaseLease and onEnvironmentDestroyLease now return { providerLeaseId, state: "destroyed" }. They do so only once the Sandbox CR or Job (and, on destroy, the pod) reads 404. The new waitForWorkloadGone in lease-lifecycle.ts polls every 500 ms for up to 20 s, below the server's 30 s plugin RPC timeout.
If the resource still exists at the deadline, or a read fails, the hook returns no receipt. That is today's behaviour, so the change never throws after a successful delete.
README entry added.
Why
The server lets a stopped run's card continue only if every remote lease has a termination receipt (server/src/services/explicit-native-continuation.ts:228; remote-execution-termination.ts:11-16). Our plugin returned void, so every cancelled or failed pod run left its card waiting on remote_cleanup forever (REN-837, REN-825). Daytona's plugin already returns these receipts. #1154 repairs the two existing leases; this PR stops new ones from getting stuck.
How verified
sh prepare.sh applies all five patches to a027f76.
vitest run test/unit in the plugin: 20 files, 211 tests pass. New tests cover release and destroy receipts, the 404-already case, a read error giving no receipt, a still-present CR or pod at the deadline, and the Job backend.
tsc --noEmit -p . in the plugin passes.
The plugin's SA already has get on sandboxes and pods in paperclip-renner (sandbox-rbac.yaml).
Not yet live. After the merge, Woodpecker builds a new build.<ts> image and Flux rolls the paperclip Deployment. Live proof: cancel a pod run by reassign, and the owner's next comment on that card starts a run.
Impact
Merging rolls the paperclip server pod, the usual image bump. Runs in flight at that moment are interrupted, so merge when the board is quiet.
Revert
Revert this PR. The next image build drops the patch.
## What
New image patch `ci/images/paperclip/ren-841-k8s-termination-receipt.patch` for `@paperclipai/plugin-kubernetes`:
- `onEnvironmentReleaseLease` and `onEnvironmentDestroyLease` now return `{ providerLeaseId, state: "destroyed" }`. They do so only once the Sandbox CR or Job (and, on destroy, the pod) reads 404. The new `waitForWorkloadGone` in `lease-lifecycle.ts` polls every 500 ms for up to 20 s, below the server's 30 s plugin RPC timeout.
- If the resource still exists at the deadline, or a read fails, the hook returns no receipt. That is today's behaviour, so the change never throws after a successful delete.
- README entry added.
## Why
The server lets a stopped run's card continue only if every remote lease has a termination receipt (`server/src/services/explicit-native-continuation.ts:228`; `remote-execution-termination.ts:11-16`). Our plugin returned `void`, so every cancelled or failed pod run left its card waiting on `remote_cleanup` forever (REN-837, REN-825). Daytona's plugin already returns these receipts. #1154 repairs the two existing leases; this PR stops new ones from getting stuck.
## How verified
- `sh prepare.sh` applies all five patches to `a027f76`.
- `vitest run test/unit` in the plugin: 20 files, 211 tests pass. New tests cover release and destroy receipts, the 404-already case, a read error giving no receipt, a still-present CR or pod at the deadline, and the Job backend.
- `tsc --noEmit -p .` in the plugin passes.
- The plugin's SA already has `get` on sandboxes and pods in `paperclip-renner` (`sandbox-rbac.yaml`).
- Not yet live. After the merge, Woodpecker builds a new `build.<ts>` image and Flux rolls the paperclip Deployment. Live proof: cancel a pod run by reassign, and the owner's next comment on that card starts a run.
## Impact
Merging rolls the paperclip server pod, the usual image bump. Runs in flight at that moment are interrupted, so merge when the board is quiet.
## Revert
Revert this PR. The next image build drops the patch.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The kubernetes sandbox plugin's release and destroy hooks returned void,
so no lease got a termination receipt and every cancelled pod run left
its card waiting on remote_cleanup. Return state destroyed once the
Sandbox CR / Job (and pod) reads 404, within 20 s; otherwise no receipt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Approved at abc09ac722. Checked: all 5 patches git-apply on upstream a027f76; plugin unit tests 211/211 pass (12 runs; one early run showed 1 transient vitest error, not reproduced in 11 reruns); tsc --noEmit clean with the built plugin-sdk; receipt {providerLeaseId,state:destroyed} satisfies remoteTerminationReceipt; deleteSandboxCr/deleteJob use Foreground propagation so workload 404 implies pod gone; waitForWorkloadGone never throws, 20 s cap below the 30 s RPC timeout; read failure returns no receipt (today's behaviour). Rollout = one non-HA pod roll.
Approved at abc09ac722b93a0de2356856e11b526fa7ab4b7d. Checked: all 5 patches git-apply on upstream a027f76; plugin unit tests 211/211 pass (12 runs; one early run showed 1 transient vitest error, not reproduced in 11 reruns); tsc --noEmit clean with the built plugin-sdk; receipt {providerLeaseId,state:destroyed} satisfies remoteTerminationReceipt; deleteSandboxCr/deleteJob use Foreground propagation so workload 404 implies pod gone; waitForWorkloadGone never throws, 20 s cap below the 30 s RPC timeout; read failure returns no receipt (today's behaviour). Rollout = one non-HA pod roll.
Ghost
merged commit 293b86a10d into master2026-10-06 14:30:55 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
What
New image patch
ci/images/paperclip/ren-841-k8s-termination-receipt.patchfor@paperclipai/plugin-kubernetes:onEnvironmentReleaseLeaseandonEnvironmentDestroyLeasenow return{ providerLeaseId, state: "destroyed" }. They do so only once the Sandbox CR or Job (and, on destroy, the pod) reads 404. The newwaitForWorkloadGoneinlease-lifecycle.tspolls every 500 ms for up to 20 s, below the server's 30 s plugin RPC timeout.Why
The server lets a stopped run's card continue only if every remote lease has a termination receipt (
server/src/services/explicit-native-continuation.ts:228;remote-execution-termination.ts:11-16). Our plugin returnedvoid, so every cancelled or failed pod run left its card waiting onremote_cleanupforever (REN-837, REN-825). Daytona's plugin already returns these receipts. #1154 repairs the two existing leases; this PR stops new ones from getting stuck.How verified
sh prepare.shapplies all five patches toa027f76.vitest run test/unitin the plugin: 20 files, 211 tests pass. New tests cover release and destroy receipts, the 404-already case, a read error giving no receipt, a still-present CR or pod at the deadline, and the Job backend.tsc --noEmit -p .in the plugin passes.geton sandboxes and pods inpaperclip-renner(sandbox-rbac.yaml).build.<ts>image and Flux rolls the paperclip Deployment. Live proof: cancel a pod run by reassign, and the owner's next comment on that card starts a run.Impact
Merging rolls the paperclip server pod, the usual image bump. Runs in flight at that moment are interrupted, so merge when the board is quiet.
Revert
Revert this PR. The next image build drops the patch.
🤖 Generated with Claude Code
Approved at
abc09ac722. Checked: all 5 patches git-apply on upstream a027f76; plugin unit tests 211/211 pass (12 runs; one early run showed 1 transient vitest error, not reproduced in 11 reruns); tsc --noEmit clean with the built plugin-sdk; receipt {providerLeaseId,state:destroyed} satisfies remoteTerminationReceipt; deleteSandboxCr/deleteJob use Foreground propagation so workload 404 implies pod gone; waitForWorkloadGone never throws, 20 s cap below the 30 s RPC timeout; read failure returns no receipt (today's behaviour). Rollout = one non-HA pod roll.