From 8d2035633b89e560132406b90d86f5cbfff602d2 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 24 Feb 2026 10:35:10 +0800 Subject: [PATCH] fix(agents): include SOUL.md, IDENTITY.md, USER.md in subagent/cron bootstrap allowlist Subagent and isolated cron sessions only loaded AGENTS.md and TOOLS.md, causing subagents to lose their role personality, identity, and user preferences. Expand MINIMAL_BOOTSTRAP_ALLOWLIST to include the three missing identity files. Closes #24852 (cherry picked from commit c33377150eeddb42c2a24f4a48c2d01b5cdf8d3e) --- src/agents/workspace.test.ts | 51 +++++++++++++++++++ src/agents/workspace.ts | 8 ++- .../bootstrap-extra-files/handler.test.ts | 7 ++- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/src/agents/workspace.test.ts b/src/agents/workspace.test.ts index 2fef954c1..0c8541789 100644 --- a/src/agents/workspace.test.ts +++ b/src/agents/workspace.test.ts @@ -11,8 +11,10 @@ import { DEFAULT_TOOLS_FILENAME, DEFAULT_USER_FILENAME, ensureAgentWorkspace, + filterBootstrapFilesForSession, loadWorkspaceBootstrapFiles, resolveDefaultAgentWorkspaceDir, + type WorkspaceBootstrapFile, } from "./workspace.js"; describe("resolveDefaultAgentWorkspaceDir", () => { @@ -141,3 +143,52 @@ describe("loadWorkspaceBootstrapFiles", () => { expect(getMemoryEntries(files)).toHaveLength(0); }); }); + +describe("filterBootstrapFilesForSession", () => { + const mockFiles: WorkspaceBootstrapFile[] = [ + { name: "AGENTS.md", path: "/w/AGENTS.md", content: "", missing: false }, + { name: "SOUL.md", path: "/w/SOUL.md", content: "", missing: false }, + { name: "TOOLS.md", path: "/w/TOOLS.md", content: "", missing: false }, + { name: "IDENTITY.md", path: "/w/IDENTITY.md", content: "", missing: false }, + { name: "USER.md", path: "/w/USER.md", content: "", missing: false }, + { name: "HEARTBEAT.md", path: "/w/HEARTBEAT.md", content: "", missing: false }, + { name: "BOOTSTRAP.md", path: "/w/BOOTSTRAP.md", content: "", missing: false }, + { name: "MEMORY.md", path: "/w/MEMORY.md", content: "", missing: false }, + ]; + + it("returns all files for main session (no sessionKey)", () => { + const result = filterBootstrapFilesForSession(mockFiles); + expect(result).toHaveLength(mockFiles.length); + }); + + it("returns all files for normal (non-subagent, non-cron) session key", () => { + const result = filterBootstrapFilesForSession(mockFiles, "agent:default:chat:main"); + expect(result).toHaveLength(mockFiles.length); + }); + + it("filters to allowlist for subagent sessions", () => { + const result = filterBootstrapFilesForSession(mockFiles, "agent:default:subagent:task-1"); + const names = result.map((f) => f.name); + expect(names).toContain("AGENTS.md"); + expect(names).toContain("TOOLS.md"); + expect(names).toContain("SOUL.md"); + expect(names).toContain("IDENTITY.md"); + expect(names).toContain("USER.md"); + expect(names).not.toContain("HEARTBEAT.md"); + expect(names).not.toContain("BOOTSTRAP.md"); + expect(names).not.toContain("MEMORY.md"); + }); + + it("filters to allowlist for cron sessions", () => { + const result = filterBootstrapFilesForSession(mockFiles, "agent:default:cron:daily-check"); + const names = result.map((f) => f.name); + expect(names).toContain("AGENTS.md"); + expect(names).toContain("TOOLS.md"); + expect(names).toContain("SOUL.md"); + expect(names).toContain("IDENTITY.md"); + expect(names).toContain("USER.md"); + expect(names).not.toContain("HEARTBEAT.md"); + expect(names).not.toContain("BOOTSTRAP.md"); + expect(names).not.toContain("MEMORY.md"); + }); +}); diff --git a/src/agents/workspace.ts b/src/agents/workspace.ts index c0bd5d633..dbef9c651 100644 --- a/src/agents/workspace.ts +++ b/src/agents/workspace.ts @@ -494,7 +494,13 @@ export async function loadWorkspaceBootstrapFiles(dir: string): Promise { const event = createHookEvent("agent", "bootstrap", "agent:main:subagent:abc", context); await handler(event); - - expect(context.bootstrapFiles.map((f) => f.name).toSorted()).toEqual(["AGENTS.md", "TOOLS.md"]); + expect(context.bootstrapFiles.map((f) => f.name).toSorted()).toEqual([ + "AGENTS.md", + "SOUL.md", + "TOOLS.md", + ]); }); });