Problem
In #4440, task(kind: "workspace") targets are created with deferUnrelatedWorkspaceConsent: true. WorkspaceTurnManager.createWorkspaceTurn then calls grantDefaultUnrelatedWorkspaceConsent() once its handle reservation is installed.
create() announces the workspace's metadata before that grant. That leaves a narrow gap of a few seconds (agent validation plus AI-settings resolution). If the user turns the consent toggle on and then off inside that gap, the deferred grant mints a fresh generation and silently undoes the opt-out. The switch shows "off" during the gap.
Suggested fix
Track pending deferred grants in memory. create() adds the ID when it defers; setUnrelatedWorkspaceConsent removes it; the deferred grant applies only while the ID is still pending. This needs no persisted field.
Found by the final readiness review of #4440; very narrow window, deferred as a non-blocker.
Generated with xum • Model: anthropic:claude-opus-5-5 • Thinking: high
Problem
In #4440,
task(kind: "workspace")targets are created withdeferUnrelatedWorkspaceConsent: true.WorkspaceTurnManager.createWorkspaceTurnthen callsgrantDefaultUnrelatedWorkspaceConsent()once its handle reservation is installed.create()announces the workspace's metadata before that grant. That leaves a narrow gap of a few seconds (agent validation plus AI-settings resolution). If the user turns the consent toggle on and then off inside that gap, the deferred grant mints a fresh generation and silently undoes the opt-out. The switch shows "off" during the gap.Suggested fix
Track pending deferred grants in memory.
create()adds the ID when it defers;setUnrelatedWorkspaceConsentremoves it; the deferred grant applies only while the ID is still pending. This needs no persisted field.Found by the final readiness review of #4440; very narrow window, deferred as a non-blocker.
Generated with
xum• Model:anthropic:claude-opus-5-5• Thinking:high