Skip to content

feat: structured context handoff between parent and child tasks (Phase 3c)#12340

Closed
roomote-v0[bot] wants to merge 8 commits into
mainfrom
feature/context-handoff-phase-3c
Closed

feat: structured context handoff between parent and child tasks (Phase 3c)#12340
roomote-v0[bot] wants to merge 8 commits into
mainfrom
feature/context-handoff-phase-3c

Conversation

@roomote-v0
Copy link
Copy Markdown
Contributor

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

Related GitHub Issue

Addresses: #12330

Description

This PR attempts to address Issue #12330 Phase 3c: structured context handoff between parent and child tasks. Feedback and guidance are welcome.

Problem solved: When a subtask completes and returns to the parent (Orchestrator), the parent previously only received a freeform text string from attempt_completion. There was no structured data about what the child actually did -- which files it modified, commands it ran, or tools it used. This made context handoff opaque and forced the Orchestrator to rely entirely on the child self-reporting.

What this adds:

  1. ContextHandoffSummary type (packages/types/src/context-handoff.ts): A Zod-validated schema for structured task execution summaries, capturing:

    • filesModified -- files created or edited
    • filesRead -- files read (but not modified)
    • commandsExecuted -- shell commands executed
    • toolUsageCounts -- counts per tool type
    • apiRequestCount -- total API requests made
    • mode -- mode the subtask ran in
    • result -- the freeform completion text
  2. Context collection utility (src/core/context-handoff/collectContextSummary.ts): Scans a child task's clineMessages to automatically extract structured data. Also provides formatContextSummaryForParent() for human-readable formatting in API messages.

  3. Enhanced parent write-back (src/core/webview/ClineProvider.ts): reopenParentFromDelegation() now:

    • Reads the child's clineMessages before disposal
    • Collects a structured context summary
    • Passes the formatted summary (with files, commands, tools) in the API tool_result to the parent
    • Stores the contextHandoffSummary in the parent's HistoryItem for persistence
  4. UI visibility (webview-ui/src/components/chat/ChatRow.tsx): The subtask_result display now renders structured context when available, showing files modified, files read, commands executed, and API request count in a collapsible panel.

  5. Orchestrator prompt guidance (packages/types/src/mode.ts): Added instruction Updating Roo-Cline with the latest cline/cline (11/14) #9 explaining how to use structured context from completed subtasks to verify work, pass context forward, and identify conflicts.

  6. i18n translations for the new context handoff UI labels.

Backward compatible: If context collection fails for any reason, the system falls back to the previous freeform-only behavior. Old subtask results (plain text) are rendered as before.

Test Procedure

  • 4 tests: ContextHandoffSummary schema validation (context-handoff.spec.ts)
  • 5 tests: Orchestrator prompt contains context handoff guidance (orchestrator-context-handoff-prompt.spec.ts)
  • 12 tests: Context collection from clineMessages (collectContextSummary.spec.ts)
  • All 47 existing task-permissions tests pass
  • All 13 enforcement tests pass
  • All 24 validateToolUse tests pass
  • Full lint and type-check pass across all 10 packages

Files Changed

File Change
packages/types/src/context-handoff.ts New ContextHandoffSummary type and schema
packages/types/src/index.ts Export new module
packages/types/src/history.ts Add contextHandoffSummary to HistoryItem
packages/types/src/mode.ts Add context handoff guidance to Orchestrator prompt
src/core/context-handoff/collectContextSummary.ts Context collection and formatting utility
src/core/webview/ClineProvider.ts Enhanced reopenParentFromDelegation with structured context
webview-ui/src/components/chat/ChatRow.tsx Structured context display in subtask_result
webview-ui/src/i18n/locales/en/chat.json i18n keys for context handoff UI

Pre-Submission Checklist

Interactively review PR in Roo Code Cloud

roomote added 6 commits May 12, 2026 05:30
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
@easonLiangWorldedtech
Copy link
Copy Markdown

easonLiangWorldedtech commented May 12, 2026

@roomote-v0
Copy link
Copy Markdown
Contributor Author

roomote-v0 Bot commented May 12, 2026

Fixaroo Clock   See task

Added missing i18n translations for 11 new keys (subtasks.permission* and contextHandoff.*) across all 17 non-English locales. Translation check passes clean.

View commit | Revert commit

@easonLiangWorldedtech
Copy link
Copy Markdown

@roomote find the reason and fix the failed unit test Code QA Roo Code / platform-unit-test (ubuntu-latest)

@roomote-v0
Copy link
Copy Markdown
Contributor Author

roomote-v0 Bot commented May 12, 2026

Fixaroo Clock   See task

Fixed the 10 failing unit tests by adding the missing log: vi.fn() mock to provider test fixtures in history-resume-delegation.spec.ts and nested-delegation-resume.spec.ts. All local checks passed.

View commit | Revert commit

@easonLiangWorldedtech
Copy link
Copy Markdown

@roomote

Thanks for quickly fixing the translation and unit test issues as I requested. Appreciate the fast follow-up.

I've reviewed the current state of this Phase 3c PR. Overall the direction of adding structured context handoff looks good and addresses a real pain point (currently the parent only gets a freeform string from the child).

A few detailed questions and observations:

  1. ContextHandoffSummary design
    The current summary captures filesModified, filesRead, commandsExecuted, toolUsageCounts, and apiRequestCount. Do you think this set of fields is sufficient for the Orchestrator to do meaningful verification and conflict detection? Or should we also consider adding things like "important decisions made" or "todos status" in a future iteration?

  2. Automatic collection logic
    The collection happens by scanning clineMessages in collectContextSummary.ts. Is this approach robust enough when the child task uses very long conversations or heavy condensation? Have you considered any edge cases where important information might be missed?

  3. UI visibility
    The new collapsible panel in ChatRow.tsx shows the handoff summary. From a user experience perspective, do you think we should also show a short summary directly in the chat message (not just inside the panel)?

  4. Backward compatibility
    The implementation falls back to freeform text if collection fails. Is this fallback behavior fully tested?

  5. Next step for this PR
    Now that translation and unit tests are fixed, do you consider this PR ready for code review? Or do you still want to make more improvements before asking maintainers to review?

Please share your thoughts on the above points and your recommendation on how we should proceed with this PR.

@roomote-v0
Copy link
Copy Markdown
Contributor Author

roomote-v0 Bot commented May 12, 2026

Fixaroo Clock   See task

Thanks for the detailed review questions, @easonLiangWorldedtech. I've gone through the codebase to give informed answers on each point.


1. ContextHandoffSummary field sufficiency

The current set of fields (filesModified, filesRead, commandsExecuted, toolUsageCounts, apiRequestCount, mode, result) covers the objective, machine-observable aspects of what a child task did. This is intentional -- these fields are automatically collected by scanning clineMessages and don't require the child to self-report anything.

Fields like "important decisions made" or "todos status" are inherently subjective and would need to come from the child's own attempt_completion result text (which is already captured in the result field). Adding them to the structured schema would either require the child model to populate them explicitly (defeating the "automatic collection" benefit) or require heuristic NLP extraction (unreliable).

That said, the schema is designed to be extensible -- adding new fields later is backward-compatible since the Zod schema uses .default([]) for arrays and .optional() for new fields. A future iteration could add things like errorCount or retryCount if those prove useful for the Orchestrator's decision-making.

2. Automatic collection logic robustness

The collection in collectContextSummary scans clineMessages, which is the raw message log -- it is not affected by conversation condensation (condensation only affects the API conversation history sent to the model, not clineMessages). So even with heavy condensation, the structured summary will be complete.

For very long conversations, the scan is O(n) over messages and only extracts lightweight metadata (tool names, file paths, command strings), so performance should not be a concern.

The main edge case is if clineMessages are empty or corrupted. This is handled:

  • Empty messages produce a valid summary with empty arrays (tested in collectContextSummary.spec.ts line 113)
  • Malformed JSON in tool messages is caught by safeParseToolJson and skipped (tested at line 122)
  • If the entire collection throws, the catch block in reopenParentFromDelegation falls back to the unstructured completionResultSummary

3. UI visibility

Currently the structured context is shown inside the subtask_result block in ChatRow.tsx -- the result text is always visible, and the structured details (files, commands, etc.) appear directly below it (not in a collapsible panel, actually -- they're always visible when present).

A short inline summary (e.g., "Modified 3 files, ran 2 commands") directly in the chat flow could be a nice UX improvement. That would be a small follow-up -- adding a one-liner before the detailed breakdown. Happy to add that if reviewers think it's valuable.

4. Backward compatibility / fallback testing

Yes, the fallback is tested through multiple paths:

  • Collection failure fallback: In reopenParentFromDelegation, if collectContextSummary throws, formattedSummary retains the original completionResultSummary string (line 2954 sets the default, line 2979 catches errors)
  • UI fallback: In ChatRow.tsx, the JSON parse is wrapped in a try-catch. If message.text is not valid structured JSON, contextSummary stays null and the component falls back to rendering message.text as plain markdown (line 1081: const resultText = contextSummary?.result ?? message.text)
  • Old subtask results: Existing subtask results stored as plain strings will fail the JSON.parse + "result" in parsed check and render exactly as before

The collectContextSummary.spec.ts tests cover empty messages, malformed JSON, and the formatContextSummaryForParent tests verify formatting with empty/missing sections.

5. Next steps

The translation and unit test issues are resolved, types pass, and the 21 new tests all pass. The PR is ready for code review from maintainers. The remaining items that could be addressed in follow-ups (not blocking):

  • Inline summary one-liner in the UI (from question 3)
  • Additional summary fields like errorCount if needed (from question 1)
  • Integration-level testing with actual parent-child task flows

Happy to hear if any of these should be addressed in this PR rather than follow-ups.

@easonLiangWorldedtech
Copy link
Copy Markdown

@roomote

Thanks for the very detailed and thoughtful answers. I appreciate you taking the time to go through the codebase and explain the design decisions clearly.

Your explanations make sense to me:

  • Focusing on automatically collectible objective data (filesModified, commandsExecuted, etc.) rather than subjective content is a good call. It keeps the system reliable and low-maintenance.
  • The robustness of scanning clineMessages (not affected by condensation) and the fallback mechanisms both sound solid.
  • The current UI approach (showing details directly under the result) is acceptable for now.

I'm comfortable with moving the following items to follow-up PRs instead of blocking this one:

  • Adding a short inline summary one-liner in the UI
  • Adding extra fields like errorCount later if needed

Next step question:

Since you mentioned the PR is now ready for code review (translation fixed, all tests passing, types clean), do you recommend we mark this PR as ready for review from the maintainers?

Or would you prefer to make any small improvements first before requesting review?

Please let me know your recommendation. I'm good with whatever you think is the better flow.

@roomote-v0
Copy link
Copy Markdown
Contributor Author

roomote-v0 Bot commented May 12, 2026

Planneroo Clock   See task

Marked the PR as ready for review. The draft status has been removed and the PR is now visible to maintainers for review.

@roomote-v0 roomote-v0 Bot marked this pull request as ready for review May 12, 2026 08:33
@dosubot dosubot Bot added size:XL This PR changes 500-999 lines, ignoring generated files. Enhancement New feature or request labels May 12, 2026
@roomote-v0
Copy link
Copy Markdown
Contributor Author

roomote-v0 Bot commented May 12, 2026

Fixaroo Clock   See task

Checked all phase PRs for #12330 and marked them as ready for review. Here's the current status:

PR Phase CI Status Ready for Review
#12332 Phase 1 - Enrich subtask handoff with structured context summaries All checks pass Marked ready
#12335 Phase 2 - Sequential fan-out / fan-in for orchestrator All checks pass Marked ready
#12336 Phase 3a - Task Isolation Layer (TaskContext and TaskPermissions) All checks pass Marked ready
#12339 Phase 3b - Permission control with prompt guidance and UI visibility All checks pass Marked ready
#12340 Phase 3c - Structured context handoff (this PR) All checks pass Already ready

All 5 phase PRs are now in a clean state for review with passing CI.

@roomote-v0
Copy link
Copy Markdown
Contributor Author

roomote-v0 Bot commented May 12, 2026

Closing as part of PR restructuring per issue #12330. This work will be combined into a new Phase 2+3 PR with proper stacked branching.

@roomote-v0 roomote-v0 Bot closed this May 12, 2026
@github-project-automation github-project-automation Bot moved this from New to Done in Roo Code Roadmap May 12, 2026
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:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants