How I built a gated multi-agent modernization loop in Cursor (and am I over-engineering it?)

Hey everyone,

I’d like to share a Cursor workflow I’ve been building — not as a finished product, but as an in-progress setup. Feedback from people who also run multi-agent loops would be great (highs, lows, dead ends).

Origin

I discovered Cursor, started with small projects, then found an old MIT-licensed CMS and decided (mostly as a hobby) to modernize it.

  • ~10 ROADMAP step IDs at the start → now 80+
  • first everything was manual (no “vibe coding”); autonomy grew step by step
  • V1: mostly one Cloud Agent → context explosion, painful token use
  • V2: thinner orchestration, specialized subagents, gated phases → tokens and context overflow dropped a lot

V2 also keeps state on disk (tickets/checkboxes/ROADMAP) and starts a fresh Cloud Agent per phase/batch, so the loop doesn’t live in one rotting chat thread.

It’s past “hobby” now — more a project I can’t stop working on.

What I’m sharing (and what I’m not)

I’m sharing the agent workflow, not asking anyone to fork the CMS. Forks are secondary.

Main ask: am I over-engineering this — too many roles/gates, or automating too much at once? Where would you simplify?

Happy to answer questions.

The loop

Cursor as a pipeline, not just a chat box:

  1. Conductor (GitHub Actions, no LLM) — outer loop / batching / chaining
  2. Orchestrator (Cloud Agent) — thin coordinator, delegates, short reports
  3. Subagents — architect, plan-reviewer, refactorer, verifier, tester, test-writer, doc-writer

(Forum doesn’t render Mermaid.)

PLAN

PLAN: architect → plan-reviewer → doc-writer → commit

EXECUTE (per checklist step, batched by Conductor)

FINALIZE

FINALIZE: PR → CI → Codecov → Bugbot → version → docs → ROADMAP

Repo (active modernization, not a polished agent framework):

Useful paths: .cursor/WORKFLOW_SUBAGENTS.md, .cursor/agents/, .cursor/rules/orchestrator-v2-*.mdc, .cursor/ROADMAP.md

Metrics

Public run metrics (duration, tokens, cache, conductor vs not):

Raw data / wiring: .github/conductor/metrics/, .github/workflows/, .github/conductor/

Measuring runs helped a lot when deciding what to keep vs cut.

Model note

I’ve been using Grok 4.5 a lot as orchestrator / doc-writer / test-writer — tight diffs, low “yapping,” cache-read-heavy in long refactor sessions. Happy to compare notes if you mix models across roles.

Feedback I’d love

  1. Over-engineering? Too many specialized agents vs fewer stronger ones?
  2. Gates: plan-reviewer + verifier + tester — overkill, or necessary at this scale?
  3. Conductor outside the LLM: outer loop in GHA vs everything in-agent — what worked for you?
  4. Failure modes: where do your loops break (context, branch/PR autonomy, flaky checks, human bottleneck)?
  5. What would you delete first if you inherited this tomorrow?

Thanks — a “don’t do it this way” reply is also a win.

1 Like

This does not look over-engineered if each gate blocks a failure you have actually observed. We reached a similar conclusion after context and token pressure: keep the orchestrator thin, move work facts to disk, and keep testing independent. The useful simplification test was whether a phase could restart from files alone and still reconstruct the owner, expected output, and completion evidence. If not, the chat was still carrying hidden state.

Thanks, that restart-from-files test is a better over-engineering check than “count the agents.”

That’s why V2 exists: a fresh Cloud Agent per phase/batch, facts on disk, orchestrator only coordinates and reports one line. The piece that actually made restarts honest was the doc-writer. After each phase/batch it records what happened (including verbatim gate feedback), not a restatement of the plan. A later agent that only git diffs still inherits chat fiction: “we already did X.” Ticket + branch doc vs. the diff is what closed that.

On a restart the original task prompt is architect-only. Everyone else gets the ticket (owner + expected output) and the branch doc (completion evidence), then aligns that against the current diff. If those three don’t reconstruct where to continue, the chat was still carrying hidden state.

The gates I kept are the ones that actually failed in V1 (plan drift, “looks done” diffs, tests that never ran). I still fail the test in a few places: conductor/GitHub Actions state, and anything a human still has to confirm on the PR.

How do you encode completion evidence so a new run can trust it, a small restart contract per phase, or ticket + living doc vs. diff like this?

We ended up separating the restart note from the evidence it points to. The note is small—task occurrence, owner, expected output, current node—but completion is trusted only when the referenced result still matches the current commit/tree and its test output can be read back. That mattered after a recovery run inherited a perfectly plausible “done” record from an older control context. I’d keep your ticket + branch doc + diff flow, but make the doc an index into immutable run evidence rather than the evidence itself.