feat: Phase 2 + Phase 3 - Sequential Fan-Out, Task Isolation, Permissions, Context Handoff (#12330)#12348
Open
roomote-v0[bot] wants to merge 11 commits into
Open
Conversation
… of #12330) Adds subtask queue support to the new_task tool, allowing the orchestrator to define multiple subtasks that execute automatically in sequence without returning to the parent between each one. This saves LLM API calls and enables more efficient multi-agent workflows. Key changes: - SubtaskQueueItem, SubtaskResult types in packages/types/src/history.ts - task_queue parameter on new_task tool (optional JSON array) - NewTaskTool parses and validates queued subtasks, stores on parent - delegateParentAndOpenChild persists queue in parent HistoryItem - reopenParentFromDelegation auto-advances queue via advanceSubtaskQueue - formatAggregatedQueueResults aggregates all results when queue completes - 9 new tests covering queue advance, exhaustion, and result formatting - All 56 existing delegation tests continue to pass
…advanceSubtaskQueue - Fix off-by-one: dispatch subtaskQueue[currentIndex] instead of subtaskQueue[nextIndex], preventing the first queued item from being skipped - Fix completedMode: fetch child history to get the child actual mode instead of incorrectly using the parent historyItem.mode - Update tests to reflect corrected queue semantics (subtaskQueueIndex represents the next item to dispatch, not the currently running item)
The Windows CI bundle step fails with EBUSY when antivirus or indexing services hold brief locks on files during copyFileSync. Add a copyFileWithRetry helper (matching the existing rmDir retry pattern) that retries up to 5 times with exponential backoff for EBUSY, EPERM, and EACCES errors.
Introduces the foundation for isolated task execution (Phase 3a of #12330): - TaskContext: immutable snapshot of mode, API config, and workspace for each task, replacing runtime reads from shared ClineProvider state - TaskPermissions: fine-grained permission boundaries (file patterns, command restrictions, read-only mode, tool allowlists) that the orchestrator can attach when spawning subtasks - TaskContextBuilder: factory functions to build TaskContext from provider state and to derive child contexts with merged permissions - Task constructor now accepts optional taskContext, using it for mode and API config initialization instead of provider.getState() - delegateParentAndOpenChild builds and passes a TaskContext to child tasks - Permission merging follows most-restrictive-wins semantics This is a pure refactor with no behavioral change -- tasks still execute sequentially, but they now carry their own isolated context. Enforcement of permission boundaries is deferred to Phase 3b/3d. Ref: #12330
Adds an optional `permissions` parameter to the `new_task` tool, allowing the Orchestrator (or any parent task) to dynamically set permission boundaries for subtasks: - New `TaskPermissions` type with filePatterns, commandPatterns, allowedTools, and deniedTools - Permission merging with most-restrictive-wins semantics for nested subtask delegation - Runtime enforcement in validateToolUse() for all permission types - Full test coverage for merging logic and enforcement Addresses Issue #12330 (Phase 3b)
…pattern merging 1. NativeToolCallParser: Remove permissions from update_todo_list cases (was erroneously added to wrong tool case, should only be on new_task) 2. deniedTools: Exempt ALWAYS_AVAILABLE_TOOLS (attempt_completion, etc.) from deniedTools check, matching the existing allowedTools behavior. Prevents parent from trapping subtask by denying completion tools. 3. Pattern merging: Replace broken exact-string intersection with layered enforcement. filePatterns/commandPatterns from parent and child are kept as separate layers (AND between layers, OR within each layer). This correctly handles narrowing: parent ["src/.*"] + child ["src/components/.*"] now allows only files matching BOTH patterns, instead of producing an empty intersection.
…ema level, simplify validation code 1. Anchor regex patterns in matchesAnyPattern with ^(?:...)$ wrapping so patterns like "src/.*" require full-path matching instead of substring matching. Prevents "evil/src/foo" from matching a "src/.*" permission. 2. Add regex validation at schema level (regexString refinement) so invalid patterns are rejected at parse time rather than silently failing at runtime. 3. Simplify duplicate file/command pattern validation in validateToolUse by unifying layered and flat code paths into a single branch that falls back to wrapping flat patterns as a single layer. 4. Remove unused matchesAnyPattern import from validateToolUse.ts. 5. Add tests for anchoring behavior, pre-anchored patterns, and invalid regex rejection at schema level.
1. Persist taskPermissions in HistoryItem so permissions survive task
restarts. Added taskPermissions field to historyItemSchema, included
it in taskMetadata output, and restored it in the Task constructor
when loading from history.
2. Add ReDoS mitigation for model-provided regex patterns:
- isSafeRegex() heuristic rejects nested quantifiers like (a+)+
and overlapping alternations in repeated groups like (a|a)+
- Max pattern length capped at 200 characters
- Both checks enforced at schema validation time via Zod refinements
- 11 new tests covering ReDoS detection and persistence round-trips
- Enhance Orchestrator customInstructions with guidance on using the permissions parameter (filePatterns, commandPatterns, allowedTools, deniedTools) including example use cases and most-restrictive-wins semantics explanation - Add permission boundaries display in the ChatRow newTask approval message so users can see what restrictions are being set before approving subtask creation - Add i18n translation keys for permission display - Add 8 new tests across packages/types and webview-ui
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR attempts to address Issue #12330 by combining Phase 2 and Phase 3 work into a single, focused PR with proper stacked branching.
What is included
Phase 2: Sequential Fan-Out / Fan-In
Phase 3a: Task Isolation Layer
TaskContextandTaskPermissionstypesPhase 3b: Permission Control
Phase 3c: Structured Context Handoff
collectContextSummaryandformatContextSummaryForParentfor rich handoff dataBranch Stack
feature/enhanced-subtask-handoff-summary(Phase 1 - PR feat: enrich subtask handoff with structured context summaries (Phase 1 of #12330) #12332)feature/phase-2-3-combined(Phase 2 + 3)Phase 3d remains deferred per discussion in #12330.
Feedback and guidance are welcome.
Interactively review PR in Roo Code Cloud