feat(subagents): lean Hermes+Claude catalog with wired isolation - #111
Conversation
🤖 CodeAnt AI — Review Status
|
Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
There was a problem hiding this comment.
divo12 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
| self._timeout_seconds = timeout_seconds | ||
| self._active: dict[str, _ActiveDelegation] = {} | ||
| self._completed: defaultdict[str, deque[DelegationCompletion]] = defaultdict(deque) | ||
| self._history: dict[str, DelegationSnapshot] = {} |
There was a problem hiding this comment.
Suggestion: _history retains every delegation snapshot indefinitely, while the manager is long-lived for the harness and no deletion or retention bound is provided. Repeated background spawns will therefore grow completed results and error strings without limit. Add bounded retention or remove snapshots after they are consumed or explicitly expired. [memory leak]
Severity Level: Major ⚠️
- ⚠️ Long-lived harnesses retain every background result.
- ⚠️ Large subagent outputs increase process memory usage.
- ❌ Sustained delegation use can cause memory pressure or termination.Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src/dream/subagents/_async_delegation.py
**Line:** 83:83
**Comment:**
*Memory Leak: `_history` retains every delegation snapshot indefinitely, while the manager is long-lived for the harness and no deletion or retention bound is provided. Repeated background spawns will therefore grow completed results and error strings without limit. Add bounded retention or remove snapshots after they are consumed or explicitly expired.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| deny_tools = frozenset(token for token in overlay if token not in _WRITE_TOKENS) | ||
| deny_writes = bool(_WRITE_TOKENS.intersection(overlay)) |
There was a problem hiding this comment.
Suggestion: The overlay contract treats entries as permission capabilities to remove, but this implementation only recognizes write tokens and otherwise interprets entries as tool names. An overlay containing network or execute therefore does not block network or execution effects; it only blocks tools literally named network or execute, allowing the child to retain capabilities the declaration says to remove. Map every supported permission effect to the corresponding PermissionRequest fields before consulting the parent gate. [security]
Severity Level: Major ⚠️
- ❌ Custom subagents can retain overlaid network capabilities.
- ❌ Execution restrictions are not enforced by the child gate.
- ⚠️ Overlay behavior diverges from projection permission semantics.Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src/dream/subagents/_overlay_gate.py
**Line:** 25:26
**Comment:**
*Security: The overlay contract treats entries as permission capabilities to remove, but this implementation only recognizes write tokens and otherwise interprets entries as tool names. An overlay containing `network` or `execute` therefore does not block network or execution effects; it only blocks tools literally named `network` or `execute`, allowing the child to retain capabilities the declaration says to remove. Map every supported permission effect to the corresponding `PermissionRequest` fields before consulting the parent gate.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| content="No async delegation manager on this session.", | ||
| is_error=True, | ||
| ) | ||
| snap = await ctx.delegations.stop(args.delegation_id) |
There was a problem hiding this comment.
Suggestion: The stop operation is keyed only by delegation_id; it does not verify that the delegation belongs to ctx.session_id. Because the manager can contain delegations for multiple sessions, any session that obtains another session's ID can cancel its background work. Pass the caller session identity to the manager and enforce ownership before stopping. [security]
Severity Level: Major ⚠️
- ❌ One session can cancel another session's background work.
- ⚠️ Shared harness delegation lifecycle lacks isolation.
- ⚠️ Long-running delegated tasks can be externally interrupted.Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src/dream/tools/builtin/delegation_stop.py
**Line:** 31:31
**Comment:**
*Security: The stop operation is keyed only by `delegation_id`; it does not verify that the delegation belongs to `ctx.session_id`. Because the manager can contain delegations for multiple sessions, any session that obtains another session's ID can cancel its background work. Pass the caller session identity to the manager and enforce ownership before stopping.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| PLAN, | ||
| VERIFY, | ||
| explore_agent, | ||
| merge_builtins, | ||
| plan_agent, | ||
| spawn_catalog_names, |
There was a problem hiding this comment.
Suggestion: The builtin resolver runs before merge_builtins, so a role that intentionally overrides explore, plan, or verify is advertised in the merged catalog but can never be selected. Resolve the merged catalog entry first, and only use the builtin resolver when no role override exists. [api mismatch]
Severity Level: Major ⚠️
- ⚠️ Custom `explore` roles are silently ignored.
- ⚠️ Advertised catalog descriptions differ from execution behavior.
- ⚠️ Role-specific tools and policies are not applied.Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src/dream/tools/builtin/spawn_subagent.py
**Line:** 27:32
**Comment:**
*Api Mismatch: The builtin resolver runs before `merge_builtins`, so a role that intentionally overrides `explore`, `plan`, or `verify` is advertised in the merged catalog but can never be selected. Resolve the merged catalog entry first, and only use the builtin resolver when no role override exists.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| session_working_dir = working_dir | ||
| override_cwd = options.metadata.get(SUBAGENT_WORKING_DIR_METADATA_KEY) | ||
| if isinstance(override_cwd, str) and override_cwd: | ||
| session_working_dir = Path(override_cwd) | ||
|
|
||
| overlay = options.metadata.get(SUBAGENT_OVERLAY_METADATA_KEY) | ||
| child_gate = permission_gate | ||
| if isinstance(overlay, tuple) and overlay: | ||
| child_gate = wrap_permission_gate(permission_gate, overlay) | ||
| context_metadata[PARENT_PERMISSIONS_KEY] = child_gate |
There was a problem hiding this comment.
Suggestion: For a worktree-isolated child, session_working_dir points at the temporary worktree, but child_gate still wraps the permission policy created for the parent's working_dir. The permission checker therefore treats writes inside the child worktree as outside the allowed repository boundary and denies mutating tools, making IsolationMode.WORKTREE unusable for the operations it is intended to isolate. Build the child permission gate against the effective session working directory while preserving the parent's policy restrictions. [api mismatch]
Severity Level: Major ⚠️
- ❌ WORKTREE children cannot modify isolated checkout files.
- ⚠️ Isolated planning or verification workflows lose write-capable tools.
- ⚠️ Child sessions report permission denials instead of useful results.Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src/dream/_factory.py
**Line:** 791:800
**Comment:**
*Api Mismatch: For a worktree-isolated child, `session_working_dir` points at the temporary worktree, but `child_gate` still wraps the permission policy created for the parent's `working_dir`. The permission checker therefore treats writes inside the child worktree as outside the allowed repository boundary and denies mutating tools, making `IsolationMode.WORKTREE` unusable for the operations it is intended to isolate. Build the child permission gate against the effective session working directory while preserving the parent's policy restrictions.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fix| snap = ctx.delegations.get(args.delegation_id) | ||
| if snap is None: | ||
| return ToolResult( | ||
| content=f"Unknown delegation_id {args.delegation_id!r}.", | ||
| is_error=True, | ||
| ) |
There was a problem hiding this comment.
Suggestion: The tool retrieves a delegation by ID without verifying that snap.session_id matches ctx.session_id. Any session that obtains or guesses another delegation ID can read its subagent names, errors, and completed output, potentially exposing sensitive work across sessions. Enforce session ownership before returning the snapshot. [security]
Severity Level: Major ⚠️
- ❌ Cross-session polling can disclose delegation outputs.
- ⚠️ Subagent errors and names may cross session boundaries.
- ⚠️ Shared-harness background lifecycle lacks endpoint ownership enforcement.Prompt for AI Agent 🤖
This is a comment left during a code review.
**Path:** src/dream/tools/builtin/delegation_get.py
**Line:** 38:43
**Comment:**
*Security: The tool retrieves a delegation by ID without verifying that `snap.session_id` matches `ctx.session_id`. Any session that obtains or guesses another delegation ID can read its subagent names, errors, and completed output, potentially exposing sensitive work across sessions. Enforce session ownership before returning the snapshot.
Validate the correctness of the flagged issue. If correct, How can I resolve this? If you propose a fix, implement it and please make it concise.
Once fix is implemented, also check other comments on the same PR, and ask user if the user wants to fix the rest of the comments as well. if said yes, then fetch all the comments validate the correctness and implement a minimal fixShip explore/plan/verify builtins, wire model/overlay/spawned_by/isolation on the live path, add delegation poll/stop for background spawns, and keep sync as the beat default with a host tool blocklist. Co-authored-by: Cursor <cursoragent@cursor.com>
Scope asynchronous delegation to its owning session and make overlays and worktree execution fail closed so the lean subagent catalog is safe to expose. Co-authored-by: Cursor <cursoragent@cursor.com>
046a777 to
985530b
Compare
Thanks for using CodeAnt! 🎉We're free for open-source projects. if you're enjoying it, help us grow by sharing. Share on X · |
There was a problem hiding this comment.
divo12 has reached the 50-credit limit for trial accounts. To continue receiving code reviews, upgrade your plan.
User description
Summary
explore/plan/verifybuiltins and wiremodel,permission_overlay,spawned_by, andIsolationModeon the live spawn pathdelegation_get/delegation_stopfor background lifecycle; strip host-only tools via Hermes-style blocklistdocs/designs/2026-08-09-lean-subagent-redesign.mdCompanion: Chorus lean roster cut (merge dream first or pin dream SHA).
Test plan
uv run pytest tests/test_subagents/explore/plan/verifyfrom a host sessiondelegation_get/delegation_stopround-tripMade with Cursor
CodeAnt-AI Description
Add safer built-in subagents with isolated execution and controllable background work
What Changed
explore,plan, andverifysubagents to every enabled spawn catalog; explore and plan are read-only, while verify returns a strict PASS, FAIL, or PARTIAL result.delegation_getanddelegation_stopfor checking or stopping background subagent work; delegation access is limited to the owning session and stopped work has its own status.Impact
✅ Safer read-only exploration and verification✅ Child edits isolated from the parent workspace✅ Clearer background delegation status and control💡 Usage Guide
Checking Your Pull Request
Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.
Talking to CodeAnt AI
Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:
This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.
Example
Preserve Org Learnings with CodeAnt
You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:
This helps CodeAnt AI learn and adapt to your team's coding style and standards.
Example
Retrigger review
Ask CodeAnt AI to review the PR again, by typing:
Check Your Repository Health
To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.