Skip to content

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
feature/enhanced-subtask-handoff-summaryfrom
feature/phase-2-3-combined
Open

feat: Phase 2 + Phase 3 - Sequential Fan-Out, Task Isolation, Permissions, Context Handoff (#12330)#12348
roomote-v0[bot] wants to merge 11 commits into
feature/enhanced-subtask-handoff-summaryfrom
feature/phase-2-3-combined

Conversation

@roomote-v0
Copy link
Copy Markdown
Contributor

@roomote-v0 roomote-v0 Bot commented May 12, 2026

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

  • Orchestrator can define multiple subtasks that execute automatically in sequence
  • Automatic transitions between subtasks without user intervention
  • Aggregated results returned to parent when queue completes

Phase 3a: Task Isolation Layer

  • Introduces TaskContext and TaskPermissions types
  • Each task carries its own isolated context for concurrent execution foundation

Phase 3b: Permission Control

  • Model-driven permission boundaries for subtasks (file patterns, command patterns, allowed/denied tools)
  • Schema-level validation with ReDoS mitigation
  • UI visibility for permission boundaries in ChatRow
  • Orchestrator prompt guidance for permissions

Phase 3c: Structured Context Handoff

  • collectContextSummary and formatContextSummaryForParent for rich handoff data
  • Context handoff includes files modified/read, commands executed, and todo progress
  • Parent receives structured summary when child completes

Branch Stack

Phase 3d remains deferred per discussion in #12330.

Feedback and guidance are welcome.

Interactively review PR in Roo Code Cloud

roomote added 11 commits May 12, 2026 14:29
… 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Enhancement New feature or request size:XXL This PR changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant