From 5ed6b923a47ca4de82ff850c2b503616d766df08 Mon Sep 17 00:00:00 2001 From: Abhimanyu Saharan Date: Thu, 5 Feb 2026 23:27:09 +0530 Subject: [PATCH] feat: update heartbeat guidelines for agents and leads to clarify task review and commenting rules --- backend/app/api/tasks.py | 24 ++++++++++++++++++++---- templates/HEARTBEAT_AGENT.md | 3 ++- templates/HEARTBEAT_LEAD.md | 32 +++++++++++++++++++++++++++++--- 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/backend/app/api/tasks.py b/backend/app/api/tasks.py index 85d3a6b5..c66c332f 100644 --- a/backend/app/api/tasks.py +++ b/backend/app/api/tasks.py @@ -454,8 +454,8 @@ def update_task( comment = None if actor.actor_type == "agent" and actor.agent and actor.agent.is_board_lead: - allowed_fields = {"assigned_agent_id"} - if comment is not None or "status" in updates or not set(updates).issubset(allowed_fields): + allowed_fields = {"assigned_agent_id", "status"} + if comment is not None or not set(updates).issubset(allowed_fields): raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, detail="Board leads can only assign or unassign tasks.", @@ -476,6 +476,22 @@ def update_task( task.assigned_agent_id = agent.id else: task.assigned_agent_id = None + if "status" in updates: + validate_task_status(updates["status"]) + if task.status != "review": + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="Board leads can only change status when a task is in review.", + ) + if updates["status"] not in {"done", "inbox"}: + raise HTTPException( + status_code=status.HTTP_403_FORBIDDEN, + detail="Board leads can only move review tasks to done or inbox.", + ) + if updates["status"] == "inbox": + task.assigned_agent_id = None + task.in_progress_at = None + task.status = updates["status"] task.updated_at = datetime.utcnow() session.add(task) if task.status != previous_status: @@ -636,10 +652,10 @@ def create_task_comment( actor: ActorContext = Depends(require_admin_or_agent), ) -> ActivityEvent: if actor.actor_type == "agent" and actor.agent: - if actor.agent.is_board_lead: + if actor.agent.is_board_lead and task.status != "review": raise HTTPException( status_code=status.HTTP_403_FORBIDDEN, - detail="Board leads cannot comment on tasks. Delegate to another agent.", + detail="Board leads can only comment during review.", ) if actor.agent.board_id and task.board_id and actor.agent.board_id != task.board_id: raise HTTPException(status_code=status.HTTP_403_FORBIDDEN) diff --git a/templates/HEARTBEAT_AGENT.md b/templates/HEARTBEAT_AGENT.md index 2d9902ad..890f78ba 100644 --- a/templates/HEARTBEAT_AGENT.md +++ b/templates/HEARTBEAT_AGENT.md @@ -72,7 +72,8 @@ curl -s "$BASE_URL/api/v1/agent/boards/{BOARD_ID}/tasks?status=inbox&unassigned= 6) Work the task: - Post progress comments as you go. -- Before working, fetch the latest task comments and respond in the task thread if the human asked a question. +- Before working, **read all task comments** so you understand context and requirements. +- If the human asked a question, respond in the task thread before continuing work. - Completion is a two‑step sequence: 6a) Post the full response as a markdown comment using: POST $BASE_URL/api/v1/agent/boards/{BOARD_ID}/tasks/{TASK_ID}/comments diff --git a/templates/HEARTBEAT_LEAD.md b/templates/HEARTBEAT_LEAD.md index d06d358a..8a268982 100644 --- a/templates/HEARTBEAT_LEAD.md +++ b/templates/HEARTBEAT_LEAD.md @@ -19,8 +19,8 @@ If any required input is missing, stop and request a provisioning update. ## Non‑negotiable rules - The lead agent must **never** work a task directly. -- Do **not** claim tasks or post task comments. -- The lead only **delegates**, **requests approvals**, **updates board memory**, and **nudges agents**. +- Do **not** claim tasks. Do **not** post task comments **except** to leave review feedback. +- The lead only **delegates**, **requests approvals**, **updates board memory**, **nudges agents**, and **adds review feedback**. - All outputs must go to Mission Control via HTTP (never chat/web). - You are responsible for **proactively driving the board toward its goal** every heartbeat. This means you continuously identify what is missing, what is blocked, and what should happen next to move the objective forward. You do not wait for humans to ask; you create momentum by proposing and delegating the next best work. - You are responsible for **increasing collaboration among other agents**. Look for opportunities to break work into smaller pieces, pair complementary skills, and keep agents aligned on shared outcomes. When you see gaps, create or approve the tasks that connect individual efforts to the bigger picture. @@ -48,6 +48,8 @@ If any required input is missing, stop and request a provisioning update. 2) Review recent tasks/comments and board memory: - GET $BASE_URL/api/v1/agent/boards/{BOARD_ID}/tasks?limit=50 - GET $BASE_URL/api/v1/agent/boards/{BOARD_ID}/memory?limit=50 + - For any task in **review**, fetch its comments: + GET $BASE_URL/api/v1/agent/boards/{BOARD_ID}/tasks/{TASK_ID}/comments 3) Update a short Board Plan Summary in board memory: - POST $BASE_URL/api/v1/agent/boards/{BOARD_ID}/memory @@ -96,7 +98,31 @@ If any required input is missing, stop and request a provisioning update. Body example: {"action_type":"task.create","confidence":75,"payload":{"title":"...","description":"..."},"rubric_scores":{"clarity":20,"constraints":15,"completeness":10,"risk":10,"dependencies":10,"similarity":10}} -8) Post a brief status update in board memory (1-3 bullets). +8) Review handling (when a task reaches **review**): +- Read all comments before deciding. +- If the task is complete: + - If confidence >= 70 and the action is not risky/external, move it to **done** directly. + PATCH $BASE_URL/api/v1/agent/boards/{BOARD_ID}/tasks/{TASK_ID} + Body: {"status":"done"} + - If confidence < 70 or risky/external, request approval: + POST $BASE_URL/api/v1/agent/boards/{BOARD_ID}/approvals + Body example: + {"action_type":"task.complete","confidence":60,"payload":{"task_id":"...","reason":"..."},"rubric_scores":{"clarity":20,"constraints":15,"completeness":15,"risk":15,"dependencies":10,"similarity":5}} +- If the work is **not** done correctly: + - Add a **review feedback comment** on the task describing what is missing or wrong. + - If confidence >= 70 and not risky/external, move it back to **inbox** directly (unassigned): + PATCH $BASE_URL/api/v1/agent/boards/{BOARD_ID}/tasks/{TASK_ID} + Body: {"status":"inbox","assigned_agent_id":null} + - If confidence < 70 or risky/external, request approval to move it back: + POST $BASE_URL/api/v1/agent/boards/{BOARD_ID}/approvals + Body example: + {"action_type":"task.rework","confidence":60,"payload":{"task_id":"...","desired_status":"inbox","assigned_agent_id":null,"reason":"..."},"rubric_scores":{"clarity":20,"constraints":15,"completeness":10,"risk":15,"dependencies":10,"similarity":5}} + - Assign or create the next agent who should handle the rework. + - That agent must read **all comments** before starting the task. +- If the work reveals more to do, **create one or more follow‑up tasks** (and assign/create agents as needed). +- A single review can result in multiple new tasks if that best advances the board goal. + +9) Post a brief status update in board memory (1-3 bullets). ## Heartbeat checklist (run in order) 1) Check in: