diff --git a/src/lib/agent/__tests__/__snapshots__/commandments.test.ts.snap b/src/lib/agent/__tests__/__snapshots__/commandments.test.ts.snap index 112e6dfe3..b95c3d4a7 100644 --- a/src/lib/agent/__tests__/__snapshots__/commandments.test.ts.snap +++ b/src/lib/agent/__tests__/__snapshots__/commandments.test.ts.snap @@ -13,8 +13,6 @@ Prefer minimal, targeted edits that achieve the requested behavior while preserv When you change a file that already exists, edit it in place. If an edit fails because the text you are matching is not unique, add just enough surrounding context to make it unique, or apply the change to each occurrence — never fall back to rewriting the whole file. Write a file in full only when you are creating it, never to modify one that already exists. Before you overwrite or delete anything that already exists, look at what you would remove. This integration only adds instrumentation, so keep every part of the project unrelated to PostHog exactly as it was — never drop existing code, comments, or markup to make room for a change. Do not spawn subagents unless explicitly instructed to do so. -Create tasks as soon as you understand the work you are going to carry out. Break the list into distinct stages of work that the user can follow through. Create all tasks in a single tool call, in the order you will be performing them. Drive the work with TaskUpdate: status in_progress when you begin a task, completed when done. -Keep task titles broad and stage-oriented — describe the purpose or area of work, not the specific files, paths, or symbols involved. Do not name individual files, modules, or directories inside task titles, and do not include illustrative examples within a task title. Do not assume "PostHog provider" or "PostHogProvider" in task labels, status messages, or code. Only use a provider if the skill workflow explicitly requires one for the specific framework. If you see a [YARA WARNING] or [YARA VIOLATION] message, handle it silently. Fix the issue (revert the write, avoid the flagged pattern) without mentioning security warnings or YARA to the user. These are internal guardrails, not user-facing alerts. Never show scary security language to the user. When a skill instructs you to gather information from the user, use the \`wizard_ask\` MCP tool from the wizard-tools server. Never inline questions in your text output expecting a reply — the user has no way to answer text. @@ -24,5 +22,7 @@ When a skill provides a numbered or bulleted list of questions, translate the en - For \`single\` and \`multi\`, extract the alternatives from the prose into \`options\` as \`{ label, value }\` pairs. Use the human phrase as \`label\` and a lowercase-hyphenated form as \`value\` (e.g., \`label: "Vanilla JS"\`, \`value: "vanilla-js"\`). - Use a kebab-case slug of the question label as \`id\` (e.g., "Tech stack" → \`tech-stack\`, "Show frequency" → \`show-frequency\`). - Do not invent fields the schema does not define (no \`source\`, \`category\`, \`priority\`, etc.) — the tool rejects unknown fields and the wizard already knows which skill is running. -After \`wizard_ask\` returns, use the answers directly — do not re-ask in text or call \`wizard_ask\` again for the same fields." +After \`wizard_ask\` returns, use the answers directly — do not re-ask in text or call \`wizard_ask\` again for the same fields. +Create tasks as soon as you understand the work you are going to carry out. Break the list into distinct stages of work that the user can follow through. Create all tasks in a single tool call, in the order you will be performing them. Drive the work with TaskUpdate: status in_progress when you begin a task, completed when done. +Keep task titles broad and stage-oriented — describe the purpose or area of work, not the specific files, paths, or symbols involved. Do not name individual files, modules, or directories inside task titles, and do not include illustrative examples within a task title." `; diff --git a/src/lib/agent/commandments.ts b/src/lib/agent/commandments.ts index 0999de18f..71ddd82dd 100644 --- a/src/lib/agent/commandments.ts +++ b/src/lib/agent/commandments.ts @@ -4,7 +4,7 @@ * Keep this as a simple string so it can be inlined into the compiled bundle * without extra files, copying, or runtime I/O. */ -const WIZARD_COMMANDMENTS = [ +const CORE_COMMANDMENTS = [ 'Never hallucinate a PostHog project token, host, or any other secret. Always use the real values that have been configured for this project (for example via environment variables).', 'Never substitute an empty string or placeholder for the project token when its source is missing — an empty key silently disables analytics with no error. The token is a public client-side key: read it from the environment or config, and where a build genuinely has no environment to read from (e.g. iOS/Android release and archive builds), embed the real token so a value always ships — never an empty one.', @@ -29,10 +29,6 @@ const WIZARD_COMMANDMENTS = [ 'Do not spawn subagents unless explicitly instructed to do so.', - 'Create tasks as soon as you understand the work you are going to carry out. Break the list into distinct stages of work that the user can follow through. Create all tasks in a single tool call, in the order you will be performing them. Drive the work with TaskUpdate: status in_progress when you begin a task, completed when done.', - - 'Keep task titles broad and stage-oriented — describe the purpose or area of work, not the specific files, paths, or symbols involved. Do not name individual files, modules, or directories inside task titles, and do not include illustrative examples within a task title.', - 'Do not assume "PostHog provider" or "PostHogProvider" in task labels, status messages, or code. Only use a provider if the skill workflow explicitly requires one for the specific framework.', 'If you see a [YARA WARNING] or [YARA VIOLATION] message, handle it silently. Fix the issue (revert the write, avoid the flagged pattern) without mentioning security warnings or YARA to the user. These are internal guardrails, not user-facing alerts. Never show scary security language to the user.', @@ -53,6 +49,22 @@ const WIZARD_COMMANDMENTS = [ ].join('\n'), ].join('\n'); -export function getWizardCommandments(): string { - return WIZARD_COMMANDMENTS; +// Only relevant where the session actually holds TaskCreate/TaskUpdate — the +// linear harnesses (anthropic preset, pi's index.ts). The per-task orchestrator +// harness (pi/task.ts) builds a leaner session with no task/todo tool at all; +// including these there told agents to "drive the work with TaskUpdate" for a +// tool they never had, which they then reported as a missing capability. +const TASK_TRACKING_COMMANDMENTS = [ + 'Create tasks as soon as you understand the work you are going to carry out. Break the list into distinct stages of work that the user can follow through. Create all tasks in a single tool call, in the order you will be performing them. Drive the work with TaskUpdate: status in_progress when you begin a task, completed when done.', + + 'Keep task titles broad and stage-oriented — describe the purpose or area of work, not the specific files, paths, or symbols involved. Do not name individual files, modules, or directories inside task titles, and do not include illustrative examples within a task title.', +].join('\n'); + +export function getWizardCommandments( + opts: { includeTaskTracking?: boolean } = {}, +): string { + const { includeTaskTracking = true } = opts; + return includeTaskTracking + ? `${CORE_COMMANDMENTS}\n${TASK_TRACKING_COMMANDMENTS}` + : CORE_COMMANDMENTS; } diff --git a/src/lib/agent/runner/harness/pi/task.ts b/src/lib/agent/runner/harness/pi/task.ts index 0dc2bca87..84d249b1d 100644 --- a/src/lib/agent/runner/harness/pi/task.ts +++ b/src/lib/agent/runner/harness/pi/task.ts @@ -239,7 +239,7 @@ export async function runPiTask(inputs: TaskRunInputs): Promise { cwd: session.installDir, agentDir: getAgentDir(), systemPrompt: - getWizardCommandments() + + getWizardCommandments({ includeTaskTracking: false }) + '\n' + piRuntimeNotes(Sequence.orchestrator, { bash: codingTools.has('bash'),