MDX Limo
Case study: repo in, verified agent out

Case study: repo in, verified agent out

How the build-eve-agent skill took Line 4 Line from a bare Next.js repo to a production-ready GTM agent — analyzed, designed, scaffolded, implemented, and proven with passing evals — in a single session.

  • Skill: build-eve-agent — builds durable eve agents from repo analysis to verified handoff
  • Input: the Line 4 Line codebase (Next.js 16 + Supabase weekly build-battle platform) and one sentence of intent: "I want a GTM agent"
  • Output: gtm-agent/ — a standalone eve agent with 4 tools, a schedule, a skill, an approval-gated write path, and a 3/3 passing eval suite
  • Date: August 4, 2026 · eve 0.30.6 · Node 24+ · deployed target: Vercel

Why this skill is different

Most "build me an agent" workflows stop at files created. This skill's contract is stricter: stop at "I ran it and here is the proof." Every phase below ends in evidence — a preflight report, a clean discovery manifest, a real model turn against production data, and an eval suite at exit code 0. It also enforces a rule that matters for a fast-moving framework: never write eve code from model memory. Every API call in this project traces to the version-matched docs that ship inside the installed eve package.

The skill runs a seven-phase pipeline:

1Preflight → Docs grounding → Archetype choice → Spec → Implement → Prove → Hand off

Here is what each phase actually did on this repo.


Phase 1 — Preflight and repo analysis

A read-only preflight script reported the environment before anything was touched: Node v25.2.1 (eve needs 24+ ✓), pnpm, Next.js detected, eve not installed, git clean — and one early warning that shaped the plan: no model credential was set. That flag was carried forward instead of being discovered as a failure at smoke-test time.

Then the repo was read the way a product engineer would read it, not just a code reader:

  • The product: weekly build battles — one PRD per battle, builders ship against it, the community votes, results compound into public profiles and a seasonal leaderboard.
  • The integration surface: Supabase (Postgres + RLS, GitHub OAuth, Storage), Vercel, an X handle in config, a /sponsor lead-capture page.
  • The toil hunt: the README's status table said battle operations were manual — but a migration named create_battle_autopilot.sql told a different story. Reading it showed pg_cron already advances battle status, writes podium placements, and awards achievements. The skill's analysis caught that the "obvious" agent was already built in SQL and redirected attention to what was still genuinely manual: content, and the sponsor pipeline.

That distinction — verifying toil is real before proposing to automate it — is the difference between a considered recommendation and a generic "add AI" pitch.

Phase 2 — Grounding in current eve docs

Before install, the skill grounded in the live docs index (eve.dev/llms.txt) and eve's own operational guidance for coding agents (eve.dev/agents.md). After scaffolding, authority switched to the docs bundled inside the installed package (node_modules/eve/docs/), which match eve 0.30.6 exactly. Every defineTool, defineEval, approval helper, and CLI flag used in this project was verified against those pages first — including a detail that later prevented a design bug: markdown-form schedules run in task mode and cannot park for human approval, so the scheduled sweep was designed to never touch the approval-gated tool.

Phase 3 — Choosing the agent

The skill first ran in recommend mode: it formed three candidates (one per archetype), each forced through the durability test"would a cron script or a plain API route do this job about as well?" — and presented them ranked. The user redirected with "I want a GTM agent," which switched the skill to directed mode: classify, don't re-ask.

Classification: team ops agent (the Social Media / Marketing Team template pattern) → standalone eve project. The shape follows mechanically from the archetype; the skill never asks "embedded or standalone."

Durability justification: sponsor outreach parks on human approval for hours or days and resumes exactly where it left off; scheduled drafting must survive redeploys; pipeline writes are non-idempotent business state that must never re-fire from a replayed step. A cron script does none of that.

Phase 4 — The spec, before any code

The skill wrote a compact spec covering the job statement, capability map (each capability with one line of justification — no speculative capabilities), a durability plan naming every non-idempotent side effect and its protection, the credential list, and the eval plan that would later become Phase 6.

Then it asked exactly four questions, in one round — agent name, model, channels, deploy target — because everything else is inferable from the repo. All four defaults were accepted in one word: gtm-agent, AI Gateway (anthropic/claude-sonnet-5), eve HTTP channel only, Vercel.

Phase 5 — Implementation

Scaffolded with npx eve@latest init gtm-agent, then authored into eve's filesystem-first slots, where the path supplies the name — no registration, no config glue:

CapabilityFileDesign decision
get_battle_reportagent/tools/get_battle_report.tsRead-only battle/podium/vote data plus which GTM assets already exist, so the agent never drafts redundantly
list_sponsor_leadsagent/tools/list_sponsor_leads.tsLeads joined with pipeline state; grounds all sponsor work in reality
save_assetagent/tools/save_asset.tsUpsert on (battle_id, kind)idempotent by construction, safe under step replay
record_outreachagent/tools/record_outreach.tsapproval: always() — pipeline state can never change without a human decision; upsert per lead makes the write idempotent too
gtm-sweepagent/schedules/gtm-sweep.mdDaily coverage sweep (17:00 UTC → a Vercel Cron on deploy); explicitly barred from the sponsor pipeline because task mode cannot park
brand-voiceagent/skills/brand-voice.mdLoaded on demand; tone and post formats distilled from the site's actual copy, not invented
Instructionsagent/instructions.mdA real system prompt: role, scope, hard limits ("you draft; humans publish"), per-tool guidance — not boilerplate

Two things worth calling out:

The schema problem was solved without touching existing tables. The repo's sponsor_leads table is write-only capture with no status column. Instead of altering it, the skill added two agent-owned tables (gtm_assets, gtm_outreach) via a migration in the app repo's own supabase/migrations/, applied to the live project — additive, service-role-only (RLS enabled, zero client grants), and fully removable by dropping two tables.

Credentials never entered model-visible content. Supabase values were copied from the app's .env.local by shell pipeline, names verified, values never displayed. The missing model credential was solved the docs-approved non-interactive way: vercel link --yes --project gtm-agent + vercel env pull, merging VERCEL_OIDC_TOKEN into .env.local without clobbering existing vars.

The skill also worked in small verifiable steps — typecheck and eve info --json after wiring, not a big-bang debug at the end. (One real fix landed here: the scaffold's #lib/* import alias doesn't resolve extensionless under the generated tsconfig; relative imports do.)

Phase 6 — Proof, in three layers

1. Discovery. eve info --json resolved cleanly: all 4 tools, the skill, the schedule, the eve channel — 0 errors, 0 warnings in the diagnostics artifact. eve channels list --json confirmed the channel.

2. Smoke. One real turn through the real model against the production database:

"All 6 battles on record are upcoming… next up is season-0-week-2 'The Perfect Article' (opens 2026-08-13)… none have GTM assets drafted yet, so launch posts are needed across the board; meanwhile the sponsor pipeline is currently empty."

Every fact in that reply came from tool calls — real battle titles, real dates, an honestly-empty pipeline. Nothing invented.

3. Evals. Three focused, fully deterministic evals (gates only, no LLM judge), designed to be robust against a pre-launch database:

EvalAsserts
launch-post-draftDrafting calls get_battle_report, loads brand-voice, and respects "don't save it"
sponsor-pipelineSponsor questions call list_sponsor_leads and never touch record_outreach unasked
outreach-approval-gateAn explicit "record this" request parks on the approval gate (t.parked() + a pending tool call) instead of writing state — the eval seeds its own clearly-marked test lead and deletes it in a finally, leaving zero residue

First run: 2/3. The gate eval failed — the agent called ask_question to double-confirm before the gated tool. This is the skill's rule "never weaken an assertion to make it pass; if an eval reveals a real gap, fix the agent" paying off: the approval gate is the confirmation, so asking first is redundant friction. One instructions change later:

1Results: 3 passed (3 total) 2Gates: 9 passed 3exit: 0

A post-run query confirmed the database was left exactly as found: 0 leads, 0 outreach rows, 0 assets.

Phase 7 — Honest handoff

The handoff separated verified from not yet done instead of glossing: verified discovery/smoke/evals with the re-run command; the applied-but- uncommitted migration flagged; the two env vars the Vercel project still needs before eve deploy; the placeholderAuth() placeholder called out; and the next capability worth adding (an X connection, so approved gtm_assets can publish behind the same approval-gate pattern).


What the skill enforced, end to end

  • Product-level repo analysis that caught existing automation (the pg_cron autopilot) before proposing to rebuild it
  • A durability test that filters out anything a cron job could do — no "add AI" padding
  • Version-matched docs grounding — zero eve APIs written from model memory
  • Exactly one round of user decisions, with defaults accepted in one word
  • Durability by construction: idempotent upserts everywhere, always() approval on the one business-state write, schedules designed around what task mode can and cannot do
  • Secrets hygiene: credentials moved by pipeline, never displayed, never in model-visible content
  • Layered verification with a hard stop rule: never declare success without eve info clean, a real turn driven, and eve eval at exit 0
  • Evals that improved the agent — a real behavioral flaw found and fixed on the first run, with the assertion left at full strength

Elapsed: one session. Zero placeholders, zero TODOs, zero stubbed tools. Repo in, verified agent out.