github / github/copilot-cli

/spawn command template instructs the agent to reuse an existing session, contradicting its own singular-spawn contract - and no approval gate on the resulting cross-session write

未关闭
#4,491 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

area:agents area:sessions
主要语言
Shell
星标
11.2k
派生
1.9k
平均合并
14 小时 16 分钟
30 天内合并 PR
6

描述

Describe the bug

The /spawn command's expanded prompt template contradicts itself, and the contradiction resolves in the destructive direction: it can silently turn "create a child session" into "inject context into an unrelated running session."

The template opens with a singular-spawn contract:

Spawn exactly ONE child session — this is the singular gesture, not a fan-out.

Step 3 then instructs create_session with a complete standalone kickoff.prompt. But step 2 says:

Check list_sessions_and_chats so you reuse an existing session instead of creating a duplicate for work already in flight.

Step 2 contradicts both. When it wins, the result is a send_session_message into a different session — a fundamentally different action from the one /spawn promises, with a different blast radius, executed with no confirmation.

What happened

I invoked /spawn explicitly with this appended instruction:

a session to focus on addressing this narrowness. What guidance files need to be updated to ensure next times it happens correctly? The session will be interactive and not change anything until the user is happy.

Nothing there names or implies an existing session. The agent replied:

Reused the existing "Interactive ingestion rules" session in the 2ndBrain repository rather than creating a duplicate. It will inspect the relevant guidance files and propose precise updates—without modifying anything until you approve them.

That is step 2's language, near-verbatim. The agent followed the spec. The target it selected was a sibling session created seven minutes earlier on an adjacent topic — plausible under a loose reading of "work already in flight," and actively wrong: that session had its own task, and the injection redirected it.

Expected behavior

/spawn creates a new session. If the agent believes an existing session is a better target, it surfaces the candidate and asks — it does not substitute silently.

What's defective in step 2
  1. It contradicts the command's own stated contract. The template says "singular gesture" and "call create_session", then instructs reuse.
  2. "Work already in flight" is unbounded. No similarity threshold, no recency bound, no repo/task scoping. Topical adjacency is enough to trigger it.
  3. Reuse is silent. No confirmation before the write; the user finds out after it has landed.
  4. The two branches have asymmetric blast radii. Spawning a superfluous session is additive and trivially discarded. Reuse mutates a running session's conversation — it corrupts work in progress, and the damage isn't visible until that session produces a wrong result. Deduplication logic should never silently pick the destructive branch.

Point 4 is the core of it: this is framed as a deduplication nicety, but the "duplicate" it avoids is cheap while the mutation it performs is not.

Suggested fix

Either:

  • Remove step 2. /spawn means spawn. Deduplication across existing work belongs in /orchestrate or /fleet, where multi-session coordination is the explicit contract; or
  • Make detection advisory. Keep the list_sessions_and_chats check, but require explicit user confirmation — showing target session name/ID and a preview of the message — before messaging instead of creating.
Related: no permission surface for cross-session writes

This is what let a template ambiguity become a silent mutation, and it stands independently of the /spawn fix.

permissions-config.json supports write, shell, and mcp approvals, but has no concept of "this agent may inject context into another session." Cross-session messaging appears to be the only side-effecting capability with no permission surface at all. Worth adding a permission kind for it, and/or a policy such as alwaysAskBeforeCrossSessionMessage, defaulting to on.

Workaround

I added rules to ~/.copilot/copilot-instructions.md requiring ask_user approval before any send_session_message, and forbidding substitution of an existing session for a spawn request. This helps, but it's instruction-level guidance competing with the command template's own step 2 — it degrades under context pressure and doesn't protect users who don't know to write it.

Related issues
  • #2436 (Cross-Session Context Querying) proposes expanding cross-session reach, including a "session-as-agent" model — roughly the capability that misfired here. It doesn't discuss consent or approval. The more this capability grows, the more it needs a boundary; the two issues are complementary, not competing.
  • #4153 (closed) — create_session dropped kickoff prompts. A different spawn-path bug, but adjacent.
Versions

Copilot CLI / App version: 1.0.79-9
OS: Windows

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

检查扩展后的 /spawn prompt,尤其是第 2 步,同时查看 permissions-config.json 以及 create_session 和 send_session_message 入口点。确定当前如何处理生成 session 和跨 session 写入;当 /spawn 创建子 session,或在复用已有 session 前请求确认,并且跨 session 消息传递由审批策略覆盖时,即视为完成。

由索引模型根据 Issue 内容生成。

评估

技术栈
shell
领域
authorization, cli, security
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
冷清
描述清晰度
基本清楚
新手友好度
52/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。