You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
task_workspace_lifecycle (PR #3940) restores the model-driven archive path for owned workspace-turn peer workspaces. When the worktree archive behavior is snapshot and the target checkout contains untracked files, archive returns requires_confirmation with the exact path list, and the caller must re-invoke with acknowledged_untracked_paths matching those paths (normalized exact-list equality, pinned across the interruption window).
This round trip is a loss-awareness acknowledgement, not a model-resistant approval boundary: the acknowledgement originates from the same model that requested the archive. A prompt-influenced owner agent can read requires_confirmation.paths and immediately echo them back, after which snapshot capture omits the untracked files and the checkout is removed — deterministic loss of new work with no user gesture. Flagged by Codex review round 22 on PR #3940 (P1 Security).
The round trip is the accepted tool contract (mirrors the historical PR 🤖 feat: add parent-owned workspace lifecycle tool #3633 design and the human UI confirmation dialog) and the issue-triage-loop skill flow depends on it.
The restored tool is scoped to durably-owned peer workspaces. A compromised owner agent already has equivalent destructive capability over that same peer workspace without touching archive: task(kind: "workspace", mode: "existing") runs full agent turns with unrestricted bash in that checkout (git clean -fdx, rm -rf, …). So the acknowledgement gate is not the barrier a prompt injection must defeat today.
The risk nevertheless remains real for user-edited untracked files in a peer workspace the user co-drove: the user's saved-but-untracked work can be discarded by a model-only acknowledgement.
Any confirmation token emitted into tool output or the transcript is model-visible and therefore echoable — a real fix cannot be a smarter token in the same channel.
Design directions
A model-resistant mitigation needs one of:
User-origin approval grant: requires_confirmation surfaces a pending approval in the UI; the user's approval is recorded backend-side (never exposed to model context) and the archive proceeds only when the backend verifies a live grant for that workspace + exact path list. The model-side acknowledged_untracked_paths becomes advisory (or is dropped).
Make model-driven lossy archives impossible: model-driven snapshot archives with untracked files are always refused (status: "error", directing the user to archive via UI); only clean checkouts are model-archivable. Simple, but breaks the documented round trip and degrades orchestrator loops on workspaces with incidental untracked files (logs, scratch).
Make snapshot non-lossy: capture untracked files into the snapshot (or a durable side-store) so nothing is lost and no confirmation is needed. Changes user-facing archive semantics too; storage-cost and secret-hygiene questions (untracked files often contain credentials).
Option 1 preserves the existing contract shape and matches the consent-surface precedent (managed plugin installation consent); option 3 removes the hazard class entirely but is the largest change. Whatever is chosen should be applied consistently across destructive model-driven workspace operations (task_remove has no confirmation at all today).
Problem
task_workspace_lifecycle(PR #3940) restores the model-driven archive path for owned workspace-turn peer workspaces. When the worktree archive behavior is snapshot and the target checkout contains untracked files, archive returnsrequires_confirmationwith the exact path list, and the caller must re-invoke withacknowledged_untracked_pathsmatching those paths (normalized exact-list equality, pinned across the interruption window).This round trip is a loss-awareness acknowledgement, not a model-resistant approval boundary: the acknowledgement originates from the same model that requested the archive. A prompt-influenced owner agent can read
requires_confirmation.pathsand immediately echo them back, after which snapshot capture omits the untracked files and the checkout is removed — deterministic loss of new work with no user gesture. Flagged by Codex review round 22 on PR #3940 (P1 Security).Why it was not changed inline on #3940
issue-triage-loopskill flow depends on it.task(kind: "workspace", mode: "existing")runs full agent turns with unrestricted bash in that checkout (git clean -fdx,rm -rf, …). So the acknowledgement gate is not the barrier a prompt injection must defeat today.Design directions
A model-resistant mitigation needs one of:
requires_confirmationsurfaces a pending approval in the UI; the user's approval is recorded backend-side (never exposed to model context) and the archive proceeds only when the backend verifies a live grant for that workspace + exact path list. The model-sideacknowledged_untracked_pathsbecomes advisory (or is dropped).status: "error", directing the user to archive via UI); only clean checkouts are model-archivable. Simple, but breaks the documented round trip and degrades orchestrator loops on workspaces with incidental untracked files (logs, scratch).Option 1 preserves the existing contract shape and matches the consent-surface precedent (managed plugin installation consent); option 3 removes the hazard class entirely but is the largest change. Whatever is chosen should be applied consistently across destructive model-driven workspace operations (
task_removehas no confirmation at all today).References
src/node/services/tools/task_workspace_lifecycle.ts.Generated with
xum• Model:anthropic:claude-fable-5• Thinking:xhigh• Cost:$366.45