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 offHere 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
/sponsorlead-capture page. - The toil hunt: the README's status table said battle operations were
manual — but a migration named
create_battle_autopilot.sqltold 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:
| Capability | File | Design decision |
|---|---|---|
get_battle_report | agent/tools/get_battle_report.ts | Read-only battle/podium/vote data plus which GTM assets already exist, so the agent never drafts redundantly |
list_sponsor_leads | agent/tools/list_sponsor_leads.ts | Leads joined with pipeline state; grounds all sponsor work in reality |
save_asset | agent/tools/save_asset.ts | Upsert on (battle_id, kind) — idempotent by construction, safe under step replay |
record_outreach | agent/tools/record_outreach.ts | approval: always() — pipeline state can never change without a human decision; upsert per lead makes the write idempotent too |
gtm-sweep | agent/schedules/gtm-sweep.md | Daily coverage sweep (17:00 UTC → a Vercel Cron on deploy); explicitly barred from the sponsor pipeline because task mode cannot park |
brand-voice | agent/skills/brand-voice.md | Loaded on demand; tone and post formats distilled from the site's actual copy, not invented |
| Instructions | agent/instructions.md | A 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:
| Eval | Asserts |
|---|---|
launch-post-draft | Drafting calls get_battle_report, loads brand-voice, and respects "don't save it" |
sponsor-pipeline | Sponsor questions call list_sponsor_leads and never touch record_outreach unasked |
outreach-approval-gate | An 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: 0A 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 infoclean, a real turn driven, andeve evalat 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.