The autonomous loop
Eva Board's defining feature is the build → verify → review → ship cycle that runs without a human in the loop. This page walks the cycle step-by-step so you know exactly what the agent is doing on your behalf when you drag a card to Develop.
Card → Develop → Agent codes → Verify ACs → Review diff → PR
▲ │ │
│ ▼ ▼
└── retry ←── FAILED REQUEST_CHANGES
The loop is owned by AgentManager in backend/internal/board/agent.go
and executed by runAgent in backend/internal/board/agent_runner.go.
A card is moved to develop (via the API or UI), which calls
AgentManager.StartAgent(cardID). That method is idempotent — only
one run per card may exist at a time.
Each StartAgent spawns a goroutine that performs the seven steps below.
1. Prepare worktree
prepareWorktree resolves the base ref (origin/<base> preferred,
falls back to local <base>) and runs git worktree add at
<repo>/../worktrees/<shortID>, creating branch
<BranchPrefix><shortID> (default prefix eva-board/).
Existing worktrees are pruned and retried once so re-runs are idempotent — you can stop a card mid-loop and restart it without manually cleaning up.
2. Initial coding-agent invocation
invokeCodingAgent builds a prompt from the card (title, description,
acceptance criteria, plus any queued feedback from the user) and hands
it to the configured codegen.Agent. The CLI is forked with the
worktree as its working directory and the prompt on stdin. Combined
output is captured (default cap: 10 MiB).
See Codegen agents for which CLIs you can swap in.
3. Auto-commit + force push
autoCommitIfNeeded stages anything the agent left dirty and commits
with a pass-numbered message. pushBranch force-pushes to origin. If
a per-user GitHub PAT is configured we splice it into the remote URL
with x-access-token so we don't mutate the shared remote config.
4. Verification loop
loop up to MaxVerifyIterations (default 3):
reload card # honours user edits to ACs mid-run
diff = git diff <base>...<branch>
result = LLM(criteria, diff)
if result.AllPassed:
break
re-invoke agent with "failed criteria" feedback
Reloading the card on every iteration means you can edit acceptance
criteria while the loop is running and the next pass picks up your
changes. Exhausting MaxVerifyIterations ends the run in failed
agent status — Eva Board does not ship code that doesn't satisfy your
criteria.
The verifier prompt + scoring lives in
backend/internal/board/verify.go.
5. Review loop
loop up to MaxReviewCycles (default 5):
verdict = LLM_review(diff) # APPROVE | REQUEST_CHANGES
if verdict == APPROVE:
break
re-invoke agent with reviewer suggestions
commit + push
re-run the FULL verification loop # don't ship code that no longer satisfies ACs
Re-verification failure during a review cycle is fatal for the run. Once the reviewer asks for changes, the new diff must pass verification again before the run can continue.
The reviewer prompt + verdict parser lives in
backend/internal/board/review.go.
6. Open PR
openPullRequest posts to GitHub via backend/internal/github/pulls.go,
persists pr_number / pr_url on the card, moves it to the PR
column, and stamps review_status = APPROVE.
The PR body includes the card title, description, and acceptance criteria so reviewers (if any) have full context without round-tripping to the board.
7. Webhook follow-up
WebhookHandler (in backend/internal/board/webhook_handler.go)
listens for GitHub pull_request events. Merged → card moves to
Done. Closed unmerged → card moves back to Review with the
GitHub state preserved on the card.
See Self-hosting → GitHub webhook setup for how to wire the webhook in your repo.
Live controls
While the loop is running you have two levers:
StopAgent(cardID)— cancels the run's context. The current agent invocation is killed, the worktree is left in place for inspection, and the card returns todevelopwithagent_status = idle.SubmitFeedback(cardID, feedback)— appends to a per-run queue that's drained into the next agent prompt. Useful when you're watching the loop iterate and want to nudge it ("don't touch the migrations directory") without stopping the run.
Real-time progress
Every transition in the loop emits an event onto an SSE broker that the UI subscribes to. You see verification scores, review verdicts, and PR creation appear in the card detail panel within ~1 second of the agent emitting them.
Event types include agent_started, agent_progress,
verification_started, verification_result, review_started,
review_result, pr_created, card_moved, and error.
See Architecture → Real-time updates for the full SSE design.