diff --git a/src/main/api-server/routes-tasks.ts b/src/main/api-server/routes-tasks.ts index 3dfafa41..ecdcadd1 100644 --- a/src/main/api-server/routes-tasks.ts +++ b/src/main/api-server/routes-tasks.ts @@ -229,9 +229,13 @@ export function registerTaskRoutes(server: AgentApiServer) { ); } } else { + // Top-level task submission goes to the assignee's manager. + // This is not a subtask — use a distinct wake reason so the + // reviewer prompt does not misframe the work as "a subtask + // you delegated". const chain = db.getChainOfCommand(token.agentId); if (chain.length > 0) { - onWakeAgent(chain[0].id, task.companyId, "subtask_completed"); + onWakeAgent(chain[0].id, task.companyId, "task_review_requested"); } } } diff --git a/src/main/orchestration/initial-user-turn.ts b/src/main/orchestration/initial-user-turn.ts index 1e81445b..e1ba7b4f 100644 --- a/src/main/orchestration/initial-user-turn.ts +++ b/src/main/orchestration/initial-user-turn.ts @@ -87,6 +87,8 @@ function buildGenericWakeTurn(trigger: string | null): string { return "An approval you requested has been decided. Act on the outcome surfaced in your briefing."; case "subtask_completed": return "A subtask you delegated is ready for review. Evaluate the work against its acceptance criteria and either accept it or request changes."; + case "task_review_requested": + return "A direct report submitted a top-level task for your review. Validate against the original acceptance criteria before deciding."; case "goal_activated": return "A goal you own has been activated. Decompose it into projects and tasks, then delegate the first batch of work."; case "report_blocked": diff --git a/src/main/prompt-builder/wake-reasons/en.ts b/src/main/prompt-builder/wake-reasons/en.ts index 9eaaee7d..0b3ecba9 100644 --- a/src/main/prompt-builder/wake-reasons/en.ts +++ b/src/main/prompt-builder/wake-reasons/en.ts @@ -5,6 +5,7 @@ export type WakeReason = | "goal_activated" | "approval_resolved" | "subtask_completed" + | "task_review_requested" | "comment" | "report_blocked" | "report_failed" @@ -69,7 +70,7 @@ export const WAKE_REASONS: Record = { subtask_completed: { title: "A subtask you delegated has been completed or moved to review.", steps: () => [ - 'Check tasks with status "in_review" from your reports', + 'Check tasks with status "in_review" whose parent task you own', "Read ALL comments on the completed subtask (GET /api/issues/{issueId}/comments)", "Review the work quality against the acceptance criteria you set", 'If acceptable: PATCH /api/issues/{issueId} with status "done" and an approving comment', @@ -77,6 +78,17 @@ export const WAKE_REASONS: Record = { "Check if the parent task can now progress", ], }, + task_review_requested: { + title: "A direct report submitted a top-level task for your review.", + steps: () => [ + 'Find the task: GET /api/agents/me/standup — look for tasksAwaitingReview', + "Read ALL comments on the task (GET /api/issues/{issueId}/comments) and any linked documents", + "Validate the work against the original acceptance criteria — not just whether it looks complete", + 'If acceptable: PATCH /api/issues/{issueId} with status "done" and a concrete approval comment', + 'If changes needed: PATCH /api/issues/{issueId} with status "in_progress" and specific, actionable feedback', + "Do not let a top-level review sit — your whole team is downstream", + ], + }, comment: { title: "A new comment has been posted on one of your tasks.", steps: () => [ diff --git a/src/shared/contracts/schemas-agents.ts b/src/shared/contracts/schemas-agents.ts index 976b55a3..1786e88c 100644 --- a/src/shared/contracts/schemas-agents.ts +++ b/src/shared/contracts/schemas-agents.ts @@ -49,5 +49,5 @@ export const heartbeatSettingsSchema = z.object({ export const triggerHeartbeatSchema = z.object({ agentId: z.string().uuid(), companyId: z.string().uuid(), - trigger: z.enum(["manual", "timer", "assignment", "goal_activated", "approval_resolved", "subtask_completed", "comment", "report_blocked", "report_failed", "recovery", "message", "peer_request", "task_continuation"]).default("manual"), + trigger: z.enum(["manual", "timer", "assignment", "goal_activated", "approval_resolved", "subtask_completed", "task_review_requested", "comment", "report_blocked", "report_failed", "recovery", "message", "peer_request", "task_continuation"]).default("manual"), });