How to Approve a Handoff in the SwarmForge Dashboard: A Complete Guide

Click the Approve button in Attention → Approvals, or POST to /api/approvals/<id>/approve to approve a handoff programmatically.

SwarmForge is an open-source AI-assisted development framework created by Uncle Bob (Robert C. Martin). Approving handoffs is a core workflow step that moves completed work between team members or AI agents. This guide covers both the dashboard UI and the underlying API implementation in the unclebob/swarm-forge repository.

Locating Pending Handoffs in the Dashboard

Pending handoffs appear in the Attention → Approvals section of the SwarmForge UI.

The dashboard structure follows this hierarchy:

  • #attention — the top-level gray "Attention" box
    • #attention-approvals — pending handoffs awaiting your review
    • #attention-clarifications — items needing additional information

Each handoff row displays:

  • An "Approval" pill label
  • The project and task identifier
  • Documents and Approve action buttons

Reviewing Before Approval

Click the Documents button on any handoff row to inspect the associated source files. This triggers the viewDoc function defined at pack_web.bb lines 24–27.

Critical check: If the handoff has unresolved remedial comments, the Approve button will be disabled. The UI enforces this via hasRemedialComments at pack_web.bb line 7010. You must resolve all comments before proceeding.

Approving a Handoff in the UI

The approval button is created by approvalButton at pack_web.bb lines 8000–8006. When clicked:

  1. The handler calls postApproval(item.id, "approve") (lines 8484–8486)
  2. A POST request fires to the backend
  3. loadState() refreshes the UI (lines 8485–8487)
  4. The handoff disappears from Approvals and moves to the appropriate workflow lane

Programmatic Approval via REST API

The same endpoint powers automation and CI/CD pipelines.


# Approve a handoff by ID (replace <ID> with the actual identifier)

curl -X POST http://localhost:8000/api/approvals/<ID>/approve

The JavaScript implementation used by the dashboard:

// pack_web.bb – lines 8484-8487
async function postApproval(id, action) {
  await fetch("/api/approvals/" + encodeURIComponent(id) + "/" + action, {
    method: "POST"
  });
  loadState();  // Refresh dashboard state
}

Server-Side Approval Implementation

The backend handler resides at pack_web.bb lines 1258–1266. It delegates to the approve! helper:

;; pack_web.bb – lines 1065-1071
(defn approve! [root id]
  (let [src (str (fs/path root ".swarmforge/handoffs/outbox/" id ".handoff"))
        dest (str (fs/path root ".swarmforge/handoffs/outbox/" id ".handoff"))]
    (spit dest (with-approved (slurp src)))))

This writes approved: true into the handoff file located at .swarmforge/handoffs/outbox/<id>.handoff.

Key Source Files

Component Path Purpose
Dashboard HTML swarmforge/scripts/pack/dashboard.html Renders the Attention → Approvals pane
UI Logic swarmforge/scripts/pack_web.bb Button creation, comment checks, API calls
Approval Endpoint swarmforge/scripts/pack_web.bb (lines 1258–1266) POST handler for /api/approvals/<id>/approve
Approval Helper swarmforge/scripts/pack_web.bb (lines 1065–1071) Writes approved: true to handoff files
Tests test/swarmforge/pack_ui_test.clj (lines 750–765) Verifies approval flow and UI updates

Summary

  • Dashboard path: Attention → Approvals → click Approve button (class btn-approve)
  • API endpoint: POST /api/approvals/<hand-off-id>/approve
  • Blocking condition: Unresolved remedial comments disable the Approve button
  • Backend effect: Sets approved: true in the handoff file at .swarmforge/handoffs/outbox/
  • Key files: pack_web.bb for UI and server logic; pack/dashboard.html for structure

Frequently Asked Questions

What happens if the Approve button is grayed out?

The Approve button is disabled when hasRemedialComments returns true (line 7010 in pack_web.bb). Open the Documents view, resolve all remedial comments on the handoff, and refresh the dashboard. The button will re-enable automatically.

Can I approve handoffs without using the dashboard?

Yes. Send a POST request directly to /api/approvals/<id>/approve as shown in the curl example above. This is useful for automation, scripted workflows, or integrating SwarmForge with external CI systems.

Where are approved handoffs stored?

Approved handoffs remain in .swarmforge/handoffs/outbox/ with approved: true written to the file. The dashboard filters them out of the Approvals pane after loadState() refreshes, but the files persist for audit trails.

How do I verify a handoff was actually approved?

Check the handoff file directly: cat .swarmforge/handoffs/outbox/<id>.handoff | grep approved. The line approved: true confirms approval. Alternatively, refresh the dashboard—the handoff should no longer appear in Attention → Approvals.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →