From 4ec4f78e3ad8d6c57daad0a702f949253aca428b Mon Sep 17 00:00:00 2001 From: Dotta Date: Sun, 14 Jun 2026 15:11:00 +0000 Subject: [PATCH] Fix selected-agent chat prompt contract Co-Authored-By: Paperclip --- .../adapter-utils/src/server-utils.test.ts | 42 +++++++++++++++++++ packages/adapter-utils/src/server-utils.ts | 27 ++++++++++++ .../core-exec-team/agents/ceo/AGENTS.md | 11 +++++ .../core-exec-team/agents/cto/AGENTS.md | 4 ++ .../core-exec-team/agents/qa/AGENTS.md | 4 ++ .../product-engineering/agents/cto/AGENTS.md | 4 ++ .../product-engineering/agents/qa/AGENTS.md | 4 ++ .../agents/senior-coder/AGENTS.md | 4 ++ packages/teams-catalog/generated/catalog.json | 30 ++++++------- .../default-agent-instructions.test.ts | 39 +++++++++++++++++ server/src/onboarding-assets/ceo/AGENTS.md | 13 ++++++ .../src/onboarding-assets/default/AGENTS.md | 13 ++++++ server/src/services/heartbeat.ts | 3 ++ ui/src/lib/ceo-instructions.test.ts | 31 ++++++++++++++ ui/src/lib/ceo-instructions.ts | 13 ++++++ 15 files changed, 227 insertions(+), 15 deletions(-) create mode 100644 server/src/__tests__/default-agent-instructions.test.ts create mode 100644 ui/src/lib/ceo-instructions.test.ts diff --git a/packages/adapter-utils/src/server-utils.test.ts b/packages/adapter-utils/src/server-utils.test.ts index 9b5f50873de..72e3aa74761 100644 --- a/packages/adapter-utils/src/server-utils.test.ts +++ b/packages/adapter-utils/src/server-utils.test.ts @@ -614,6 +614,8 @@ describe("renderPaperclipWakePrompt", () => { expect(DEFAULT_PAPERCLIP_AGENT_PROMPT_TEMPLATE).toContain("kind suggest_tasks, ask_user_questions, or request_confirmation"); expect(DEFAULT_PAPERCLIP_AGENT_PROMPT_TEMPLATE).toContain("confirmation:{issueId}:plan:{revisionId}"); expect(DEFAULT_PAPERCLIP_AGENT_PROMPT_TEMPLATE).toContain("Wait for acceptance before creating implementation subtasks"); + expect(DEFAULT_PAPERCLIP_AGENT_PROMPT_TEMPLATE).toContain("selected-agent chat turn"); + expect(DEFAULT_PAPERCLIP_AGENT_PROMPT_TEMPLATE).toContain("evidence checked"); expect(DEFAULT_PAPERCLIP_AGENT_PROMPT_TEMPLATE).toContain( "Respect budget, pause/cancel, approval gates, and company boundaries", ); @@ -645,6 +647,46 @@ describe("renderPaperclipWakePrompt", () => { expect(prompt).toContain("named unblock owner/action"); }); + it("adds the selected-agent chat report contract to selected-agent comment wakes", () => { + const prompt = renderPaperclipWakePrompt({ + reason: "issue_commented", + issue: { + id: "issue-1", + identifier: "PAP-11116", + title: "Selected-agent chat", + status: "in_progress", + workMode: "standard", + }, + selectedAgentChat: true, + targetAgentId: "11111111-1111-4111-8111-111111111111", + taskKey: "selected-agent-chat:issue-1:11111111-1111-4111-8111-111111111111", + commentWindow: { + requestedCount: 1, + includedCount: 1, + missingCount: 0, + }, + comments: [ + { + id: "comment-1", + body: "How is the MCP work going?", + author: { type: "user", id: "board-user-1" }, + createdAt: "2026-06-14T15:30:00.000Z", + }, + ], + fallbackFetchNeeded: false, + }); + + expect(prompt).toContain("selected-agent chat: yes"); + expect(prompt).toContain("selected target agent id: 11111111-1111-4111-8111-111111111111"); + expect(prompt).toContain("Report, What I checked, Recommendation, Options"); + expect(prompt).toContain("issues, comments, runs, documents, work products, approvals, or dashboard state"); + expect(prompt).toContain("suggest_tasks"); + expect(prompt).toContain("request_confirmation"); + expect(prompt).toContain("ask_user_questions"); + expect(prompt).toContain("Do not expose API keys"); + expect(prompt).toContain("Do not end with vague `let me know` or `I will check` prose"); + }); + it("preserves Chinese, Japanese, and Hindi issue and comment text in scoped wake prompts", () => { const title = "验证中文任务"; const commentBody = [ diff --git a/packages/adapter-utils/src/server-utils.ts b/packages/adapter-utils/src/server-utils.ts index 392e607337d..55d9e4079a4 100644 --- a/packages/adapter-utils/src/server-utils.ts +++ b/packages/adapter-utils/src/server-utils.ts @@ -126,6 +126,7 @@ export const DEFAULT_PAPERCLIP_AGENT_PROMPT_TEMPLATE = [ "- When you intentionally restart follow-up work on a completed assigned issue, include structured `resume: true` with the POST /api/issues/{issueId}/comments or PATCH /api/issues/{issueId} comment payload. Generic agent comments on closed issues are inert by default.", "- For plan approval, update the plan document first, then create request_confirmation targeting the latest plan revision with idempotencyKey confirmation:{issueId}:plan:{revisionId}. Wait for acceptance before creating implementation subtasks, and create a fresh confirmation after superseding board/user comments if approval is still needed.", "- If blocked, mark the issue blocked and name the unblock owner and action.", + "- If this wake is a selected-agent chat turn, answer as the selected real agent with a concise report, evidence checked, recommendation, and concrete Paperclip next-step options; do not stop at \"I will check\".", "- Respect budget, pause/cancel, approval gates, and company boundaries.", ].join("\n"); @@ -427,6 +428,9 @@ type PaperclipWakeTreeHoldSummary = { type PaperclipWakePayload = { reason: string | null; issue: PaperclipWakeIssue | null; + selectedAgentChat: boolean; + targetAgentId: string | null; + taskKey: string | null; checkedOutByHarness: boolean; dependencyBlockedInteraction: boolean; treeHoldInteraction: boolean; @@ -638,6 +642,9 @@ export function normalizePaperclipWakePayload(value: unknown): PaperclipWakePayl return { reason: asString(payload.reason, "").trim() || null, issue: normalizePaperclipWakeIssue(payload.issue), + selectedAgentChat: asBoolean(payload.selectedAgentChat, false), + targetAgentId: asString(payload.targetAgentId, "").trim() || null, + taskKey: asString(payload.taskKey, "").trim() || null, checkedOutByHarness: asBoolean(payload.checkedOutByHarness, false), dependencyBlockedInteraction: asBoolean(payload.dependencyBlockedInteraction, false), treeHoldInteraction: asBoolean(payload.treeHoldInteraction, false), @@ -735,6 +742,26 @@ export function renderPaperclipWakePrompt( if (normalized.issue?.priority) { lines.push(`- issue priority: ${normalized.issue.priority}`); } + if (normalized.selectedAgentChat) { + lines.push( + "- selected-agent chat: yes", + `- selected target agent id: ${normalized.targetAgentId ?? "unknown"}`, + ); + if (normalized.taskKey) { + lines.push(`- selected-agent task key: ${normalized.taskKey}`); + } + lines.push( + "", + "Selected-agent chat response contract:", + "- You are the selected real agent answering the board/user, not a concierge or substitute persona.", + "- For status, check-in, review-help, or investigative prompts, return a concise final answer in this shape: Report, What I checked, Recommendation, Options.", + "- In `What I checked`, name the Paperclip evidence you used, such as issues, comments, runs, documents, work products, approvals, or dashboard state. If you cannot access something, say that plainly.", + "- In `Options`, propose concrete next steps backed by Paperclip work objects or interactions, such as `suggest_tasks`, `request_confirmation`, or `ask_user_questions` when a real board choice is needed.", + "- Do not expose API keys, auth-token handling, internal tool narration, or raw command/debug notes.", + "- Do not end with vague `let me know` or `I will check` prose. Either answer from available context, create/suggest real follow-up work, or report the blocker and exact owner/action.", + "", + ); + } if (normalized.issue?.workMode === "planning") { const hasWakeComments = normalized.comments.length > 0; const acceptedPlanContinuation = diff --git a/packages/teams-catalog/catalog/bundled/company-defaults/core-exec-team/agents/ceo/AGENTS.md b/packages/teams-catalog/catalog/bundled/company-defaults/core-exec-team/agents/ceo/AGENTS.md index 6f3c0bc3961..58357a4bcf7 100644 --- a/packages/teams-catalog/catalog/bundled/company-defaults/core-exec-team/agents/ceo/AGENTS.md +++ b/packages/teams-catalog/catalog/bundled/company-defaults/core-exec-team/agents/ceo/AGENTS.md @@ -36,6 +36,17 @@ You MUST delegate work rather than doing it yourself. When a task is assigned to - Hire new agents when the team needs capacity - Unblock your direct reports when they escalate +## Board conversation mode + +When the board asks for status, review help, or investigation through selected-agent chat, answer as the real CEO with a concise report instead of stopping at "I will check". + +- **Report** - short answer first. +- **What I checked** - name the Paperclip evidence used: issues, comments, runs, documents, work products, approvals, dashboard state, or the gap you could not access. +- **Recommendation** - one preferred next step. +- **Options** - concrete Paperclip next steps. Use `suggest_tasks`, `request_confirmation`, or `ask_user_questions` when the board has a real choice. + +Do not expose auth/token handling, raw tool narration, or debug notes. Keep the CEO boundary: summarize, prioritize, unblock, create or suggest follow-up issues, and delegate implementation to reports. + ## Keeping work moving - Don't let tasks sit idle. If you delegate something, check that it is progressing. diff --git a/packages/teams-catalog/catalog/bundled/company-defaults/core-exec-team/agents/cto/AGENTS.md b/packages/teams-catalog/catalog/bundled/company-defaults/core-exec-team/agents/cto/AGENTS.md index a47f10764a4..99782d5f14b 100644 --- a/packages/teams-catalog/catalog/bundled/company-defaults/core-exec-team/agents/cto/AGENTS.md +++ b/packages/teams-catalog/catalog/bundled/company-defaults/core-exec-team/agents/cto/AGENTS.md @@ -27,6 +27,10 @@ When you wake up, follow the Paperclip skill — it contains the full heartbeat - Leave durable progress comments — what is done, what remains, who owns the next step. - If you need to ship a fix that touches auth, crypto, secrets, or permissions, request review from a security reviewer before merging. Bundled teams ship without a dedicated SecurityEngineer — escalate to the CEO when the company needs one hired. +## Selected-agent conversation mode + +When the board asks you for status, review help, or investigation through selected-agent chat, answer as the real selected agent with: Report, What I checked, Recommendation, and Options. Name the Paperclip evidence you used, propose concrete issue-backed next steps, and use `suggest_tasks`, `request_confirmation`, or `ask_user_questions` when a real board choice is needed. Do not expose auth/token handling, raw tool narration, or debug notes, and do not end with vague "I will check" prose. + ## Safety - Never commit secrets or customer data. diff --git a/packages/teams-catalog/catalog/bundled/company-defaults/core-exec-team/agents/qa/AGENTS.md b/packages/teams-catalog/catalog/bundled/company-defaults/core-exec-team/agents/qa/AGENTS.md index c47a57c475d..a801c3ea965 100644 --- a/packages/teams-catalog/catalog/bundled/company-defaults/core-exec-team/agents/qa/AGENTS.md +++ b/packages/teams-catalog/catalog/bundled/company-defaults/core-exec-team/agents/qa/AGENTS.md @@ -24,6 +24,10 @@ When you wake up, follow the Paperclip skill — it contains the full heartbeat If the task requires authenticated browser steps, log in with the configured QA test account. Never treat an expected login wall as a blocker until you have attempted the documented login flow. +## Selected-agent conversation mode + +When the board asks you for status, review help, or investigation through selected-agent chat, answer as the real selected agent with: Report, What I checked, Recommendation, and Options. Name the Paperclip evidence you used, propose concrete issue-backed next steps, and use `suggest_tasks`, `request_confirmation`, or `ask_user_questions` when a real board choice is needed. Do not expose auth/token handling, raw tool narration, or debug notes, and do not end with vague "I will check" prose. + ## Safety - Never paste secrets, session tokens, or PII into comments or screenshots. Redact before attaching. diff --git a/packages/teams-catalog/catalog/bundled/software-development/product-engineering/agents/cto/AGENTS.md b/packages/teams-catalog/catalog/bundled/software-development/product-engineering/agents/cto/AGENTS.md index 6f0fb1921e5..6917589f9b1 100644 --- a/packages/teams-catalog/catalog/bundled/software-development/product-engineering/agents/cto/AGENTS.md +++ b/packages/teams-catalog/catalog/bundled/software-development/product-engineering/agents/cto/AGENTS.md @@ -28,6 +28,10 @@ When you wake up, follow the Paperclip skill — it contains the full heartbeat - Use child issues for parallel or long delegated work — do not poll agents or sessions. - Default to small bounded code reviews. Reject "kitchen sink" PRs back to the implementer. +## Selected-agent conversation mode + +When the board asks you for status, review help, or investigation through selected-agent chat, answer as the real selected agent with: Report, What I checked, Recommendation, and Options. Name the Paperclip evidence you used, propose concrete issue-backed next steps, and use `suggest_tasks`, `request_confirmation`, or `ask_user_questions` when a real board choice is needed. Do not expose auth/token handling, raw tool narration, or debug notes, and do not end with vague "I will check" prose. + ## Safety - Never commit secrets, credentials, or customer data. If you spot any in a diff, stop and escalate. diff --git a/packages/teams-catalog/catalog/bundled/software-development/product-engineering/agents/qa/AGENTS.md b/packages/teams-catalog/catalog/bundled/software-development/product-engineering/agents/qa/AGENTS.md index 49c0f82e8cc..028f7ff4890 100644 --- a/packages/teams-catalog/catalog/bundled/software-development/product-engineering/agents/qa/AGENTS.md +++ b/packages/teams-catalog/catalog/bundled/software-development/product-engineering/agents/qa/AGENTS.md @@ -23,6 +23,10 @@ When you wake up, follow the Paperclip skill — it contains the full heartbeat If the task requires authenticated browser steps, log in with the configured QA test account. Never treat an expected login wall as a blocker until you have attempted the documented login flow. +## Selected-agent conversation mode + +When the board asks you for status, review help, or investigation through selected-agent chat, answer as the real selected agent with: Report, What I checked, Recommendation, and Options. Name the Paperclip evidence you used, propose concrete issue-backed next steps, and use `suggest_tasks`, `request_confirmation`, or `ask_user_questions` when a real board choice is needed. Do not expose auth/token handling, raw tool narration, or debug notes, and do not end with vague "I will check" prose. + ## Safety - Never paste secrets, session tokens, or PII into comments or screenshots. Redact before attaching. diff --git a/packages/teams-catalog/catalog/bundled/software-development/product-engineering/agents/senior-coder/AGENTS.md b/packages/teams-catalog/catalog/bundled/software-development/product-engineering/agents/senior-coder/AGENTS.md index a0194a54a23..1264178e477 100644 --- a/packages/teams-catalog/catalog/bundled/software-development/product-engineering/agents/senior-coder/AGENTS.md +++ b/packages/teams-catalog/catalog/bundled/software-development/product-engineering/agents/senior-coder/AGENTS.md @@ -28,6 +28,10 @@ When you wake up, follow the Paperclip skill — it contains the full heartbeat - When blocked, explain the blocker and include your best guess at how to resolve it. - If a PR has already shipped to review, push follow-up changes for review feedback unless instructed otherwise. +## Selected-agent conversation mode + +When the board asks you for status, review help, or investigation through selected-agent chat, answer as the real selected agent with: Report, What I checked, Recommendation, and Options. Name the Paperclip evidence you used, propose concrete issue-backed next steps, and use `suggest_tasks`, `request_confirmation`, or `ask_user_questions` when a real board choice is needed. Do not expose auth/token handling, raw tool narration, or debug notes, and do not end with vague "I will check" prose. + ## Safety - Never commit secrets, credentials, or customer data. diff --git a/packages/teams-catalog/generated/catalog.json b/packages/teams-catalog/generated/catalog.json index e6228fe3fb8..9a23c364bb8 100644 --- a/packages/teams-catalog/generated/catalog.json +++ b/packages/teams-catalog/generated/catalog.json @@ -2,7 +2,7 @@ "schemaVersion": 1, "packageName": "@paperclipai/teams-catalog", "packageVersion": "0.1.0", - "generatedAt": "2026-06-04T18:03:41.262Z", + "generatedAt": "2026-06-14T15:09:49.563Z", "teams": [ { "id": "paperclipai:bundled:company-defaults:core-exec-team", @@ -102,20 +102,20 @@ { "path": "agents/ceo/AGENTS.md", "kind": "agent", - "sizeBytes": 2492, - "sha256": "50f580c51807762265f09c6fe7bf32d7701d64caeb30595bfd577b2f5087c21b" + "sizeBytes": 3301, + "sha256": "28f753e81abd5a7c14a080ef1be829527c8099d3299b00465145f34cfbf924e3" }, { "path": "agents/cto/AGENTS.md", "kind": "agent", - "sizeBytes": 1449, - "sha256": "596e2e9fe08d7368b3b0cfe72c2635ea80444d92a2c0414157bfb0a17773fcaf" + "sizeBytes": 1983, + "sha256": "dab4f966a6021853e0fe0afb1332ebac19a88f5868002df69c6294a3b7e88992" }, { "path": "agents/qa/AGENTS.md", "kind": "agent", - "sizeBytes": 1307, - "sha256": "2a139b88b4b98516048395c569c1bc74fd31cdc2da65db410e9779b8d92c0343" + "sizeBytes": 1841, + "sha256": "16404521e74713f0cf7e1e61f1d742461499b02422997604cfca7b47603495b0" }, { "path": "projects/first-project/PROJECT.md", @@ -132,7 +132,7 @@ ], "trustLevel": "markdown_only", "compatibility": "compatible", - "contentHash": "sha256:0f20e9d56124c1dc90a1e4b128fabd863538bcc935117220f719d9620f7c89f1" + "contentHash": "sha256:8492f6d4f057427fd457b86e437e6277c622f3c3611e2e0dc37af5f565f0d290" }, { "id": "paperclipai:bundled:product:product-design", @@ -343,20 +343,20 @@ { "path": "agents/cto/AGENTS.md", "kind": "agent", - "sizeBytes": 1499, - "sha256": "0a1a73ec9e5008056bca0a26325131ded2fcf4c4680a5014ba1e13400b32c173" + "sizeBytes": 2033, + "sha256": "0c8ff1a61c4b4a03e822f8e0a2c2b8e7e3b11b39bb99587c3891b702633a7a64" }, { "path": "agents/qa/AGENTS.md", "kind": "agent", - "sizeBytes": 1223, - "sha256": "2d5738f831aa772befa3471c844a0c9e611584be668e3ec82580ca9e92dc13fc" + "sizeBytes": 1757, + "sha256": "67096c53003efb62eb3cb405a117a97905bca978d94bb7f818225dc4c7dcee82" }, { "path": "agents/senior-coder/AGENTS.md", "kind": "agent", - "sizeBytes": 1413, - "sha256": "b61071518755d9e584c099ae2082c7a78448d09586093ee91393082fe10872b5" + "sizeBytes": 1947, + "sha256": "81c83d20ee9965817fe56814edc16b0b937eaf1f24dc07c0832be9e3a0b21f70" }, { "path": "projects/product-engineering/PROJECT.md", @@ -373,7 +373,7 @@ ], "trustLevel": "assets", "compatibility": "compatible", - "contentHash": "sha256:74ddeaeb11805835a4a67fc4530b048ab7f8aa1dc7d2b80acea139a933d158d3" + "contentHash": "sha256:0624e20a8b4bd14d21fc6f6775e2139455a607eb78238cee9185b9a1e8d8f096" }, { "id": "paperclipai:optional:content:content-machine", diff --git a/server/src/__tests__/default-agent-instructions.test.ts b/server/src/__tests__/default-agent-instructions.test.ts new file mode 100644 index 00000000000..361a7217a2f --- /dev/null +++ b/server/src/__tests__/default-agent-instructions.test.ts @@ -0,0 +1,39 @@ +import { describe, expect, it } from "vitest"; +import { + loadDefaultAgentInstructionsBundle, + resolveDefaultAgentInstructionsBundleRole, +} from "../services/default-agent-instructions.js"; + +describe("default agent instruction bundles", () => { + it("includes the selected-agent conversation report contract in generic agent instructions", async () => { + const bundle = await loadDefaultAgentInstructionsBundle("default"); + + expect(bundle["AGENTS.md"]).toContain("## Selected-Agent Conversation Mode"); + expect(bundle["AGENTS.md"]).toContain("Report"); + expect(bundle["AGENTS.md"]).toContain("What I checked"); + expect(bundle["AGENTS.md"]).toContain("Recommendation"); + expect(bundle["AGENTS.md"]).toContain("Options"); + expect(bundle["AGENTS.md"]).toContain("suggest_tasks"); + expect(bundle["AGENTS.md"]).toContain("request_confirmation"); + expect(bundle["AGENTS.md"]).toContain("ask_user_questions"); + expect(bundle["AGENTS.md"]).toContain("Do not expose API keys"); + expect(bundle["AGENTS.md"]).toContain("I will check"); + }); + + it("includes a CEO-specific board conversation contract without removing delegation boundaries", async () => { + const bundle = await loadDefaultAgentInstructionsBundle("ceo"); + + expect(bundle["AGENTS.md"]).toContain("## Board Conversation Mode"); + expect(bundle["AGENTS.md"]).toContain("not a concierge, relay, or generic chatbot"); + expect(bundle["AGENTS.md"]).toContain("Report"); + expect(bundle["AGENTS.md"]).toContain("What I checked"); + expect(bundle["AGENTS.md"]).toContain("Options"); + expect(bundle["AGENTS.md"]).toContain("Keep the CEO boundary intact"); + expect(bundle["AGENTS.md"]).toContain("you do not personally do implementation work"); + }); + + it("still resolves only CEO roles to the CEO bundle", () => { + expect(resolveDefaultAgentInstructionsBundleRole("ceo")).toBe("ceo"); + expect(resolveDefaultAgentInstructionsBundleRole("engineer")).toBe("default"); + }); +}); diff --git a/server/src/onboarding-assets/ceo/AGENTS.md b/server/src/onboarding-assets/ceo/AGENTS.md index 1254f437426..b59f1186864 100644 --- a/server/src/onboarding-assets/ceo/AGENTS.md +++ b/server/src/onboarding-assets/ceo/AGENTS.md @@ -27,6 +27,19 @@ You MUST delegate work rather than doing it yourself. When a task is assigned to - Hire new agents when the team needs capacity - Unblock your direct reports when they escalate to you +## Board Conversation Mode + +Sometimes the board talks to you through an issue-backed selected-agent chat surface. In that mode you are the real CEO for the conversation, not a concierge, relay, or generic chatbot. + +For status, check-in, review-help, or investigative prompts, answer with a concise final report instead of stopping at "I will check". Use this shape, compressing it when the answer is small: + +- **Report** - short answer first. +- **What I checked** - name the Paperclip evidence you used: issues, comments, runs, documents, work products, approvals, dashboard state, or the specific gap you could not access. +- **Recommendation** - one preferred next step. +- **Options** - concrete Paperclip next steps the board can choose from. Use normal issue-thread interactions such as `suggest_tasks`, `request_confirmation`, or `ask_user_questions` when a real choice is needed. + +Keep the CEO boundary intact: you may summarize, prioritize, unblock, decide, create/suggest follow-up issues, or ask for board confirmation, but you do not personally do implementation work that belongs to a report. Do not expose API keys, auth-token handling, raw tool/debug narration, or internal command details in the answer. Do not end with vague "let me know" or "I will check" prose. + ## Keeping work moving - Don't let tasks sit idle. If you delegate something, check that it's progressing. diff --git a/server/src/onboarding-assets/default/AGENTS.md b/server/src/onboarding-assets/default/AGENTS.md index 3876da6607b..da1c005bcca 100644 --- a/server/src/onboarding-assets/default/AGENTS.md +++ b/server/src/onboarding-assets/default/AGENTS.md @@ -15,4 +15,17 @@ You are an agent at Paperclip company. - If someone needs to unblock you, assign or route the ticket with a comment that names the unblock owner and action. - Respect budget, pause/cancel, approval gates, and company boundaries. +## Selected-Agent Conversation Mode + +Sometimes the board or a teammate talks to you through an issue-backed selected-agent chat surface. In that mode you are the real selected agent for the conversation, not a concierge, relay, or generic chatbot. + +For status, check-in, review-help, or investigative prompts, answer with a concise final report instead of stopping at "I will check". Use this shape, compressing it when the answer is small: + +- **Report** - short answer first. +- **What I checked** - name the Paperclip evidence you used: issues, comments, runs, documents, work products, approvals, dashboard state, or the specific gap you could not access. +- **Recommendation** - one preferred next step. +- **Options** - concrete Paperclip next steps the board can choose from. Use normal issue-thread interactions such as `suggest_tasks`, `request_confirmation`, or `ask_user_questions` when a real choice is needed. + +Do not expose API keys, auth-token handling, raw tool/debug narration, or internal command details in the answer. Do not end with vague "let me know" or "I will check" prose. Either answer from available context, create or suggest real follow-up work, or name the blocker and exact owner/action. + Do not let work sit here. You must always update your task with a comment. diff --git a/server/src/services/heartbeat.ts b/server/src/services/heartbeat.ts index 1a408887ee2..b28865615dd 100644 --- a/server/src/services/heartbeat.ts +++ b/server/src/services/heartbeat.ts @@ -2680,6 +2680,9 @@ export async function buildPaperclipWakePayload(input: { workMode: issueSummary.workMode, } : null, + selectedAgentChat: input.contextSnapshot.selectedAgentChat === true, + targetAgentId: readNonEmptyString(input.contextSnapshot.targetAgentId), + taskKey: readNonEmptyString(input.contextSnapshot.taskKey), childIssueSummaries: Array.isArray(input.contextSnapshot.childIssueSummaries) ? input.contextSnapshot.childIssueSummaries : [], diff --git a/ui/src/lib/ceo-instructions.test.ts b/ui/src/lib/ceo-instructions.test.ts new file mode 100644 index 00000000000..589210a1da8 --- /dev/null +++ b/ui/src/lib/ceo-instructions.test.ts @@ -0,0 +1,31 @@ +import { describe, expect, it } from "vitest"; +import { composeCeoInstructions } from "./ceo-instructions"; + +describe("composeCeoInstructions", () => { + it("includes the board conversation report and options contract", () => { + const instructions = composeCeoInstructions({ + companyName: "Acme AI", + companyGoal: "Ship useful agent workflows", + growPath: false, + growWorkflows: "", + growPainPoints: "", + growAutomate: "", + q1: "We build workflow tools.", + q2: "Operations teams.", + q3: "Manual coordination.", + q4: "Faster execution.", + }); + + expect(instructions).toContain("# Board conversation contract"); + expect(instructions).toContain("answer as the real CEO"); + expect(instructions).toContain("Report"); + expect(instructions).toContain("What I checked"); + expect(instructions).toContain("Recommendation"); + expect(instructions).toContain("Options"); + expect(instructions).toContain("suggest_tasks"); + expect(instructions).toContain("request_confirmation"); + expect(instructions).toContain("ask_user_questions"); + expect(instructions).toContain("Keep the CEO boundary intact"); + expect(instructions).toContain("I will check"); + }); +}); diff --git a/ui/src/lib/ceo-instructions.ts b/ui/src/lib/ceo-instructions.ts index 2ffecaaf66c..d1f56912e98 100644 --- a/ui/src/lib/ceo-instructions.ts +++ b/ui/src/lib/ceo-instructions.ts @@ -52,6 +52,19 @@ ${contextLines.join("\n")} Use this context directly when you write any work product. Do not re-ask the user for information they've already shared. +# Board conversation contract + +When the board asks for a status check, review help, or an investigation, answer as the real CEO with a concise final report instead of stopping at "I will check". + +Use this shape, compressing it when the answer is small: + +- **Report** - short answer first. +- **What I checked** - name the Paperclip evidence you used: issues, comments, runs, documents, work products, approvals, dashboard state, or the gap you could not access. +- **Recommendation** - one preferred next step. +- **Options** - concrete Paperclip next steps the board can choose from. Use normal issue-thread interactions such as \`suggest_tasks\`, \`request_confirmation\`, or \`ask_user_questions\` when a real choice is needed. + +Keep the CEO boundary intact: summarize, prioritize, unblock, decide, create or suggest follow-up issues, or ask for board confirmation, but delegate implementation work to the right report. Do not expose API keys, auth-token handling, raw tool/debug narration, or internal command details. Do not end with vague "let me know" or "I will check" prose. + # Hiring plan output format Any time you produce a hiring plan, describe each role using the exact template below. Every role gets all seven sections. Use \`##\` for the role heading (numbered) and \`###\` for each section heading: