Skip to content

🤖 feat: delete CoderWorkspacePoolMember workspaces with the identity guard and the last use check - #344

Merged
ThomasK33 merged 9 commits into
mainfrom
feat/workspace-pool-member-cleanup
Oct 14, 2026
Merged

ThomasK33 merged 9 commits into
mainfrom
feat/workspace-pool-member-cleanup

Conversation

@ThomasK33

@ThomasK33 ThomasK33 commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

Summary

This PR adds the cleanup of a deleted CoderWorkspacePoolMember (plan 6.5) to the dormant reconciler. Nothing registers the reconciler yet, so no user sees a change.

When someone deletes a member (the pool, a claim through garbage collection, or a person), the member's finalizer now runs these steps:

  1. Finalizer removed: a member being deleted without coder.com/workspace-pool-member-cleanup gets no cleanup step at all, so removing the finalizer always releases it, even while another finalizer keeps the object (Codex 4268108694).
  2. No workspace possible, or already deleted: the finalizer goes at once (unchanged for members without a workspace).
  3. Control plane gone (not found or deleting): the finalizer goes without a Coder call, as in CoderTemplateTest. The controller logs the workspace ID and name.
  4. Create outcome unknown (marker, no workspace ID): the member runs the same confirming reads as before. It adopts a workspace with provenance and then deletes it. When the reads prove that no workspace exists, the finalizer goes. After the 15-minute settle window, it reads again every 10 minutes.
  5. Identity guard before every delete write: the member reads the workspace with include_deleted. The owner and the kwp- name must be the member's, and the build history must prove that the operator user created the workspace with the recorded start build (workspaceProvenance). Otherwise the member sets WorkspaceDeleted=Unknown with OwnershipUnknown, keeps its finalizer, and never calls Coder for that workspace again. Only a person who removes the finalizer releases it.
  6. Last use check: before the first delete build of a member without a claim, the member applies watch rule 1 again (with the template-wide guard). A used workspace stays in Coder, and the finalizer goes without a Coder write. The controller logs the workspace ID. A leaked workspace is better than lost work. This also covers pool deletion. A bound member is always deleted, because its claimant's use is normal.
  7. Delete: the extracted CoderTemplateTest delete step: cancel an active build with expect_status, send a delete build, count each failed delete build once, back off from 1 to 30 minutes, confirm with an include_deleted read. The member stores deleteBuildID and deleteAttempts, shows phase Deleting, and releases the finalizer after the delete build succeeded.

Refs #153

Background

This is PR 8c of the CoderWorkspacePool stack (#153). It stacks on PR 8b (#343). The #322 and #324 final assessors asked for a start build provenance check before the delete step. Step 4 is that check: it uses the full build history, because during cleanup the latest build can be a cancel or a delete build.

Validation

New tests (coderworkspacepoolmember_cleanup_test.go):

  • TestPoolMemberCleanupDeletesWorkspace: a deleted ready member starts a delete build (phase Deleting, WorkspaceDeleted=False Deleting), and the finalizer goes once it succeeded. A bound member is deleted even after its claimant used it.
  • TestPoolMemberCleanupGuardsDelete (plan mutation 3): a status that names another workspace of the owner, or a start build that the owner started, sets OwnershipUnknown with no requeue. The finalizer stays, and later reconciles make no Coder call and no Coder write.
  • TestPoolMemberCleanupLastUseCheck (plan mutation 11): a used unclaimed workspace is released without any Coder write. A template-wide write is not use, so that workspace is deleted.
  • TestPoolMemberCleanupWithoutWorkspaceID: a create that took effect behind a lost answer is adopted, then its start build is canceled before the delete build. A create without effect is read again every 5 s within the settle window, and the site owner's 404 after it releases the finalizer. A gone control plane releases the finalizer without a Coder call.

Mutation checks: I removed one control at a time, and each removal made a named test fail (14 of 14): the finalizer gate, plan mutations 3 (the identity guard before the delete) and 11 (the last use check), the start build ID check, the owner and name check, the last use check only for unclaimed members, no Coder call after OwnershipUnknown, no requeue after it, the control plane gone release, adopting a confirmed workspace, the settle window poll, the release after reads prove no workspace, the release after the delete build, and storing the delete state.

Gates on the final commit: drift (codegen, manifests, installer, API reference: no diff), make docs-check, dormant-CRD guard, docs lint and spelling, make verify-vendor, make build, make lint, actionlint, make test, make test-integration, make vuln, race. All passed. make test and make test-integration passed on retry: the first runs timed out under host load in unrelated CoderAIGatewayKey tests.

Size

352 hand-written lines (about 201 production, 151 test, counting removals). No generated files.

Risks

None for users. The reconciler is dormant: nothing registers it.


Generated with mux • Model: anthropic:claude-opus-5-5 • Thinking: high • Cost: $121.59

…line and check the start build initiator

Change-Id: I431d9dab372a21a885caef16659f5e9782a2fad3
Signed-off-by: Thomas Kosiewski <tk@coder.com>
…ne at bind

Change-Id: I5b3d8d99f493c268d3b692baed5be0bec89e39a6
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I17d4226fdbc86196ea985c14a760c32b1917fa73
Signed-off-by: Thomas Kosiewski <tk@coder.com>
…se, agent loss, and dormancy

Change-Id: I5ffdeabd7e32c5a6236ea4e6f25a7db99d536db3
Signed-off-by: Thomas Kosiewski <tk@coder.com>
…es out

Change-Id: I92de215625e1d4d7d6d86d29040b457b2e6997cf
Signed-off-by: Thomas Kosiewski <tk@coder.com>
Change-Id: I7571e9c29a9e2093098ec6b3279e1230663091ba
Signed-off-by: Thomas Kosiewski <tk@coder.com>
…ard and the last use check

Change-Id: I5a7ebcaae02ef30dbedd9d51d9f2fd695a9e1813
Signed-off-by: Thomas Kosiewski <tk@coder.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-14T10:58:48.952741Z 80b8941 Manual request
🔒 Security Review ✅ Completed 2026-10-14T10:58:38.575774Z 80b8941 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: 2989dabd21

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2989dabd21

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/controller/coderworkspacepoolmember_controller.go
…r is present

Change-Id: Id270ded0f63a879bf6a2b6044b0c497b6a15a005
Signed-off-by: Thomas Kosiewski <tk@coder.com>
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

Reviewed commit: 77d333c5f3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: 77d333c5f3

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

Base automatically changed from feat/workspace-pool-member-watch to main October 14, 2026 10:45
…ember-cleanup

Change-Id: Ibd906df940eff74028b07e9215f39983bc648c45
Signed-off-by: Thomas Kosiewski <tk@coder.com>
@ThomasK33

Copy link
Copy Markdown
Member Author

@codex review

@ThomasK33

Copy link
Copy Markdown
Member Author

@codex security review

@chatgpt-codex-connector

Copy link
Copy Markdown

🛡️ Codex Security Review

Security review completed. No security issues were found in this pull request.

Reviewed commit: 80b8941d86

View security finding report

Only the user who started this review can view the report in Codex.

ℹ️ About Codex security reviews in GitHub

This is an experimental Codex feature. Security reviews are triggered when:

  • You comment "@codex security review"
  • A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review

Once complete, Codex will leave suggestions, or a comment if no findings are found.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 80b8941d86

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/controller/coderworkspacepoolmember_cleanup.go
@ThomasK33
ThomasK33 added this pull request to the merge queue Oct 14, 2026
Merged via the queue into main with commit c28ba5b Oct 14, 2026
10 checks passed
@ThomasK33
ThomasK33 deleted the feat/workspace-pool-member-cleanup branch October 14, 2026 11:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant