Skip to content

fix(core): inherit parent agent denies on child sessions - #475

Merged
shuv1337 merged 2 commits into
integration-v2from
cursor/plan-subagent-denies-1bce
Nov 5, 2026
Merged

shuv1337 merged 2 commits into
integration-v2from
cursor/plan-subagent-denies-1bce

Conversation

@shuv1337

@shuv1337 shuv1337 commented Nov 5, 2026 •

Copy link
Copy Markdown
Owner

Issue for this PR

None. Ports upstream b8ca71d309 (anomalyco#26597) onto V2. Do not merge until review.

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Plan mode denies edit on the plan agent. A child session only copied the parent session rules, which are empty in plan mode, so a general or custom child could still edit, write, and patch.

Child creation now appends the parent agent's deny rules after the inherited session rules. Allows and asks stay on the parent agent. Session rules are evaluated after the child agent's rules, and the last match wins, so a copied parent allow would grant something the child had refused. An explicit permissions array on Session.create still replaces inheritance.

When the parent names an agent that is missing after activation, either because the location has no agent service or the registry has no record, the child gets the same deny-all fallback permission checks use for a missing agent (* * deny). A parent with no agent id still inherits only its session rules.

The subagent tool, command subagents, and restart recovery all create children through Session.create without a ruleset, so they pick this up. Restart waits for plugin activation before reading the parent agent, because a cold location may still be starting.

How did you verify your code works?

packages/core/test/plan-subagent-permission.test.ts fails on the previous inheritance and passes with this change. It creates real child sessions and evaluates permissions through Permission.Service, Permission.evaluate, and the tool snapshot:

  • Plan parent, empty session permissions: general and custom children are denied edit outside the workspace and inside the plan directory. edit, write, and patch drop out of the tool snapshot. read stays.
  • Reusing that child id, including with permissions: [], keeps the deny. Switching the child to a permissive agent still denies edit.
  • A non-plan parent deny (shell) is forwarded. Session read and external_directory denies stay. A parent edit allow does not let a read-only child edit.
  • A parent agent id with no registry record denies the child's edit and read. A parent with no agent id still allows edit and keeps its session read deny.
  • A parent location with no agent service denies a child whose own rules allow everything. An agentless parent in that location still allows edit.

bun typecheck in packages/core passed. plan-subagent-permission.test.ts and session-create.test.ts: 50 pass, 0 fail. Pre-push typecheck: 40 tasks successful.

Head: 4949a81429db3f334f672d9c0345468318dd3681

Differences from upstream: V2 keeps the full parent session ruleset, then appends denies, so a parent-agent deny wins over an earlier session allow. The plan-directory allow is not copied, so children cannot edit plan files even though the plan agent can. Asks are not forwarded. Children that already exist are not rewritten when a follow-up reuses them or when the parent later switches into plan mode.

Visual

<svg xmlns="http://www.w3.org/2000/svg" width="240" height="72" viewBox="0 0 240 72" fill="none">
  <style>
    .gate { transform-box: fill-box; transform-origin: center; animation: block 1.8s ease-in-out infinite; }
    @keyframes block { 0%, 100% { opacity: 1 } 50% { opacity: .35 } }
    @media (prefers-reduced-motion: reduce) { .gate { animation: none } }
  </style>
  <g fill="none" stroke="currentColor" stroke-width="1.5">
    <rect x="12" y="18" width="70" height="36" rx="6"/>
    <rect x="158" y="18" width="70" height="36" rx="6"/>
    <path d="M82 36h28" opacity=".55"/>
    <path class="gate" d="M118 22l16 28M134 22l-16 28"/>
    <path d="M142 36h16" opacity=".55"/>
  </g>
  <text x="47" y="40" text-anchor="middle" fill="currentColor" font-family="ui-sans-serif,sans-serif" font-size="12">Plan</text>
  <text x="193" y="40" text-anchor="middle" fill="currentColor" font-family="ui-sans-serif,sans-serif" font-size="12">edit</text>
</svg>

Screenshots / recordings

Permission behavior only. No UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR
Open in Web Open in Cursor 

Plan mode's edit deny lives on the agent, so a child that only copied the parent session rules could still edit. Append parent-agent denies after the inherited session rules without copying allows or asks.
A parent session that names an agent still fails closed when that agent is missing from the registry or the location has no agent service. Parents with no agent id keep inheriting only their session rules.
@shuv1337
shuv1337 merged commit c241449 into integration-v2 Nov 5, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants