cd /news/ai-agents/building-a-software-factory-two-curs… · home › topics › ai-agents › article
[ARTICLE · art-163991] src=gist.github.com ↗ pub= topic=ai-agents verified=true sentiment=↑ positive

Building a software factory: two Cursor cloud agents that take Asana tickets to production (AI Tinkerers talk, Rating Captain)

Mateusz Piwnicki, speaking at AI Tinkerers, detailed a "software factory" in which two Cursor cloud agents, Roman and Bogdan, take Asana tickets through planning, coding, independent review, merge, deploy and live verification. Across 259 opened pull requests, 232 were merged, 208 of them by the agents after an independent review and written merge gate, at a computed cost of about $7 per merged PR on IdeaShirt. Piwnicki said the setup leaves him roughly 10 hours of his own engineering per week on top of running the factory.

by read5 min views1 publishedNov 3, 2026

You're welcome to use this. If it becomes useful, credit Mateusz Piwnicki.

Two Cursor cloud agents take Asana tickets all the way to production: plan, code, independent review, merge, deploy, live check, hand back. This gist is the sanitised playbook behind the AI Tinkerers talk by Mat (Rating Captain, IdeaShirt, Yax Software).

  • Roman works on Rating Captain, a local-SEO SaaS (Laravel, several apps in one monorepo).
  • Bogdan works on IdeaShirt, an e-commerce store, plus two acquired brands with their legacy code.

Account ids, server names, Asana ids, emails, and customer names are replaced with placeholders.

| PRs opened | 259 | | Merged | 232 | | Merged by the agents, after independent review and a written merge gate | 208 | | Merged by a human, after review | 24 | | Computed cost per merged PR (IdeaShirt, two-week median) | about $7, typically two agent runs | | My own engineering per week, on top of running the factory | about 10 hours |

  1. Intake. A ticket is assigned to the agent's Asana user. A scheduled Cursor Automation (the dispatcher) checks the inbox and decides: start, resume, or skip. It never writes code.
  2. Work. One Cursor cloud agent per ticket, started withPOST https://api.cursor.com/v1/agents . Grok 4.7 builds. Opus designs the UX and reviews the code. The reviewer never sees the author's reasoning.
  3. Ship. PR, merge gate, deploy, check the live URL, hand back in Asana with a comment.

Both agents:

  • Cursor Cloud Agents. One VM per ticket, started by the dispatcher through the Cloud Agents API.
  • Asana. Each agent is a real Asana user. It takes tickets, comments, reassigns, adds tags, uploads files.
  • GitHub and GitHub Actions. Branch, PR, review, merge. Each app has its own deploy workflow. A backup token covers auth failures.
  • AWS. Cursor's short-lived identity token is exchanged for a one-hour IAM role. Production access is SSM Run Command on three named servers. No VPN, no stored keys. See03-aws-trust-policy.json and04-aws-permissions-policy.json .
  • Cloudflare. Cache checks, and a purge skill for when stale pages survive a deploy.
  • Models. Grok 4.7 (standard speed, never Fast) does the work. Opus designs the UX and reviews the code. Grok checks the live site.

Bogdan, the e-commerce agent, also has:

  • Search Console, GA4, Google Ads, Meta Ads. Our own MCP servers on Cloudflare Workers, behind a bearer token and an IP allowlist. The dispatcher attaches them on every run.

  • Google Tag Manager. A skill on the Tag Manager API that audits the containers.

  • Product feeds for Google Merchant Center, Facebook, and TikTok.

  • Production database. Read-only queries through SSM. After a merge he checks that the merged SQL script is applied before handing the ticket over for testing.

  • Live checks behind Cloudflare. A secret cookie lets his QA browser past bot protection without turning it off.

  • One Asana board, three brands. The dispatcher routes each ticket to the right repo.

  • MCP for data you own and host, mostly read: analytics, ads, Search Console. One server serves humans and agents. Our database MCP servers accept onlySELECT ,SHOW ,DESCRIBE ,EXPLAIN .

  • Plain API or CLI for the agent's own identity and actions: Asana as the agent, GitHub, AWS, Cloudflare.

Traps we hit:

  • An MCP OAuth login is stored once per server URL. Our second Asana workspace silently reused the first workspace's login. The agent in that workspace now uses a personal access token over REST.

  • MCP servers passed when an agent is created are not kept on follow-ups. Send them on every run.

  • Every MCP tool description sits in the agent's context on every turn. A curl example inside a skill costs nothing until the agent opens it.

  • Fast mode is the default on paid plans and costs about twice as much. Send params: [{"id":"fast","value":"false"}] onevery create and every follow-up . A follow-up without a model goes back to the default.

  • A subagent started without an explicit model inherits the parent's model, Fast included. Name the model on every subagent call.

  • Every follow-up re-reads the whole conversation. Wake an agent only when a human did something new on the ticket. Never send "continue working".

  • When the latest run's cacheReadTokens reaches 8,000,000, archive the agent and start a fresh one on the same branch and PR from an ~80-line brief file kept on the branch. Memory lives in the repo, not the chat.

Effect on IdeaShirt: median computed cost per merged PR went from about $18 (Fast week) to about $10, then about $7 after the long-thread handoff. In one week, 13 PRs averaged $6.53 and one old, long thread cost $60.15.

  • "I can't" requires evidence. An agent kept replying "no VPN, I can't check production" two days after it was given production access, because the first sentence of its rule said "this VM is not on the VPN". It may now only say it can't reach something after the command fails, quoting the error.

  • One repair, then escalate. A one-line fix hit an unrelated upstream build failure. "Stay until the deploy is green" plus "fix the cause" produced nine follow-up PRs, and a human merged seven of them. Now: a "not my fault" test, one repair per task, then stop with aBuild failed! comment assigned to a human.

  • Merge rights by what could break, not by diff size. A one-line billing change waits for a human. A 500-line bug fix doesn't. Human-only: money, login, SEO, infrastructure, migrations, customer emails, ads tracking, new flows. When unsure, it's not safe.

  • Green pipeline is not done. Done is the live URL working after every deploy step, including after-scripts.

  • 01-worker-rule.md : the loop each ticket agent follows.

  • 02-dispatcher.md : the scheduled dispatcher, with the create and follow-up calls.

- `03-aws-trust-policy.json` : IAM trust for Cursor's OIDC identity.
- `04-aws-permissions-policy.json` : SSM Run Command on three tagged servers, plus log queries.

Read-only on production is a rule in the prompt, not an IAM permission: AWS-RunShellScript runs as root. If you copy this, lock it down with a custom SSM document.

── more in #ai-agents 4 stories · sorted by recency
── more on @cursor 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/building-a-software-…] indexed:0 read:5min 2026-11-03 · —