##spec-first
Requirements are authored before a line of code — permanent, immutable IDs; superseded rows tombstoned with a pointer, never deleted. Ambiguity has an address: an agent reads the requirement instead of inventing behavior.
prompt engineer · hermosa beach, ca
I turn prototypes into versioned specs, specs into dependency-wired ticket graphs, and loop agent teams over the graph until the epic is drained — with human judgment concentrated into a few named gates. My job is to make the AI engineering SDLC itself a designed product.
I build the systems engineering teams use to ship production software with AI agents — spec-covered, test-proven, compliance-aware. The answer isn't better models. It's better engineering around the models.
The last year has been an arc. It started as prompt engineering — ablation studies, evaluation harnesses, load-bearing-component analysis. It became context engineering — behavioral specs across the full Claude Code toolkit (CLAUDE.md, Skills, Rules, Hooks, Memory). It's now loop and graph engineering: a pipeline that turns a designer prototype into a versioned requirements catalog, the catalog into a dependency-wired ticket graph, and the graph into parallel agent lanes that build, verify, and ship — while a human decides only at a handful of named gates.
The pipeline produces four durable artifacts on every run — code, specs, learnings, and end-to-end tests — not just code. Specs include non-functional catalogs promoted from a real threat model: security baseline, HIPAA overlay, PHI handling. This is the line between agentic engineering and vibe-coding, and I live on the engineering side of it.
The proof point: one real epic — 45 dependency-wired tickets — drained by agent lanes in about 35 operator-paced hours. 114 requirements authored before a line of code, ~92 PRs across 3 repos, 111/111 e2e scenarios green, zero reverts. Eight human decisions steered all of it. Concentrate judgment. Automate the span. Compound the learnings.
How much engineering it actually takes to let agent teams ship production software — and where a human still has to decide.
"The loop is the easy part. The graph, the gates, and the memory are the engineering — and they're what let agents ship software you'd actually merge."
agentic loops & graphs — self-improving systems
Every principle below serves one goal: concentrate human judgment into a few named gates, automate the span between them, and make every run leave the system smarter.
Requirements are authored before a line of code — permanent, immutable IDs; superseded rows tombstoned with a pointer, never deleted. Ambiguity has an address: an agent reads the requirement instead of inventing behavior.
Tickets are thin vertical slices wired by blocked-by edges. Readiness becomes computable — the loop derives the ready set from the graph, no one hand-orders the work. Columns are build waves; tall columns are exactly where parallel lanes pay off; the critical path is the floor.
Most agentic workflows interrupt constantly or never stop. The third path: concentrate every human decision into a few named, high-leverage gates — scope, epic approval, drain start, PR merge. Each ruling lands in a durable artifact so no downstream stage re-asks it.
Autonomy is a dial (L0 assisted → L3 auto-merge), not a boolean — with hard ceilings the agent cannot raise. Heavy-risk changes (models, migrations, auth, money, sensitive data) cap at human-merge. A run that authored a new requirement never auto-merges.
Every run leaves four artifacts behind: code, specs, learnings, e2e tests. Learnings are captured before ship and auto-applied by future planning runs — one session's debugging becomes the next session's head start. The system's failures become its rules.
A green you didn't personally observe is not a green. Lanes report; the lead re-runs gates, reads the diff, drives the live app, and queries the database for ground truth. One verdict per check — "not run" is not a verdict.
Subagents never return prose to be re-parsed. Every fan-out defines a JSON schema and the harness retries until output validates — orchestration consumes typed data, and disagreement becomes typeable.
Spawn budgets, 3-strike root-cause rules, round caps, token reserves, broken-baseline hard stops. Budgets are the contract that makes a multi-agent system debuggable — without them, "the agent kept trying" is indistinguishable from progress.
Prompts are hypotheses, not products. Ablation testing reveals load-bearing components; cross-model validation proves generalization; LLM-as-judge scales evaluation. This Level-3 prompting discipline is where the whole arc started.
Systematic approach to reliable AI agent development
A comprehensive methodology and toolkit for making AI coding agents reliable at scale. Demonstrates measurable acceleration in project delivery (8→6→4→3 weeks) through friction-driven context refinement, hierarchical CLAUDE.md specifications, and autonomous verification loops.
impact
Demonstrates how systematic context management transforms agents into reliable executors at scale. Behavioral constraints in CLAUDE.md encode values as persistent rules rather than per-prompt instructions — friction-driven refinement is reinforcement learning at the workflow level. Directly applicable to any team scaling AI coding agents in production.
AI persona dialogue system with prompt ablation research
Open-source platform for multi-persona philosophical dialogues, paired with systematic prompt engineering research. The ablation study tests which system prompt components are load-bearing vs decorative when embodying famous historical figures — including cross-model validation across Haiku, Sonnet, and Opus.
impact
Research contribution to prompt engineering: for well-known personas, minimal prompts work as well as elaborate ones — and this holds across model capability tiers. Even Haiku produces recognizable Nietzsche with just "You are Friedrich Nietzsche." The finding has implications for prompt optimization, context-window efficiency, and how teams reason about what their system prompts are actually buying.
Production work — written up in industry-portable terms.
One real feature: a designer prototype decomposed into a versioned spec, minted as a 45-slice dependency graph, and drained by parallel agent lanes in ~35 operator-paced hours. Presented publicly as "Agentic Loops and Graphs" (Planet DDS AI Meetup #3).
The funnel: parallel readers mapped the prototype against shipped specs and surfaced that it secretly bundled three initiatives — the highest-leverage human decision of the project was a scope gate that deleted roughly two epics of accidental scope before any code existed. Then 122 requirement candidates were reconciled against the shipped catalogs (19 conflicts, all resolved; 6 operator product rulings), and 114 requirements were authored with permanent, immutable IDs — before a single line of implementation.
The graph: the spec was minted into 45 thin, vertical, end-to-end slices wired by blocked-by edges. Readiness became computable — the loop derived the ready set directly from the tracker, so no one hand-ordered the work. Laid out by build depth, the graph's columns are waves: every slice in a column became buildable the moment the prior wave merged. Tall columns are exactly where two lanes ran in parallel; the critical path set the floor.
The loop: each lane ran the same nine-step spine — pre-flight, sync real data, implement with a file-domain-isolated strike team, verify against the running app, multi-lens review, fix every finding, iterate until clean, capture learnings, honor the autonomy dial. Verification was tiered to risk, not convenience: the drain lead re-ran every gate personally, read every diff, drove the live app via browser automation, and queried the database directly for ground truth on write paths. 111/111 end-to-end scenarios green; the defects were caught upstream in each lane's QA loop, so the final gate acted as confirmation.
The human budget: eight decisions steered all 45 tickets — a scope gate, a reversal blessing, six product rulings, the ticket-mint authorization, the drain gate, pacing, and mid-build product questions recorded for a PM instead of decided by an agent. Every one of the ~92 PRs was read and approved by a human. Autonomy over execution — never over judgment.
// the drain, replayed — sanitized interactive record
The real 45-slice dependency graph from the epic, laid out by build depth: every column is a wave — each slice became buildable the moment the previous wave merged. Tall columns are exactly where the loop ran lanes in parallel; the critical path (22 hops) is the floor. Click a slice to trace what it waited on and what it unblocked. Identifiers and titles are scrubbed; the topology, risk tiers, verification depth, and merge timeline are real.
44 of 45 slices shipped & merged; the one exclusion (S-09) was ruled human-owned at the drain gate and deliberately gates nothing. Gaps in the timeline are operator pacing — the loop's reconcile-first design makes resume free.
// outcome
A repeatable pipeline, not a lucky run: prototype → spec → ticket graph → drain, with human judgment concentrated into eight named gates and every merge backed by observed verification. The loop is the easy part — the graph, the gates, and the memory are the engineering.
The engine under the drain: 13 compound commands, 6 spec commands, and a deterministic debate engine sharing one build spine.
Two pipelines share one engine. Small work enters through a triage front door and runs one lane to a PR; big features enter through the spec-decomposition funnel and end in an epic drain. Every lane — solo or drained — runs the same spine: real-data sync, a file-domain-isolated strike team with a QA loop, live verification against the running app, multi-lens read-only review, fix-every-finding iteration, and learnings capture before ship.
Plans argue for their lives before execution: the debate engine runs a 3-lens reviewer panel (correctness, coverage, consistency) that traces the requirement through the codebase before reading the plan, then an author agent validates every blocker against real code — as deterministic workflow code with severity gates, round caps, token reserves, and a formal dispute-escalation path that hands genuine disagreements to the human, never auto-resolves them.
Everything runs under budgets and stop conditions: spawn caps, a 3-strike rule keyed on root-cause tags (not failure counts), broken-baseline hard stops, and an operator-owned-decision rule — a genuine product call always stops the loop and hands back. Subagents never return prose; every fan-out is schema-validated, so orchestration consumes typed data.
// outcome
The same engine serves supervised daily work and unattended epic drains — the throttle changes, the guarantees don't. It fails closed: budgets exceed or schemas don't validate and the workflow halts and escalates instead of silently degrading.
Surveyed another team's prompt suite, identified five patterns that travel, adopted them into a different greenfield codebase, and wrote the playbook.
Prompt engineering is converging across teams, but nobody's harvesting what travels. I surveyed a brownfield team's suite — roughly 6,800 lines, 21 slash commands, 5 subagent templates — the way you'd read another engineer's library: what's generalizable versus what's load-bearing on their specific context.
Five patterns travelled: risk-driven mode selection, file-domain isolation between subagents, task-log files as durable phase contracts, active-fixer review agents, and frontmatter-registered subagents. I adopted all five into a different team's greenfield suite and wrote a teammate-facing report so other AI engineers could pilot the same patterns without re-doing the archaeology.
// outcome
Multi-team capability lift from one engineer's archaeology. The meta-skill is pattern extraction across codebases — knowing which conventions survive translation and which are scaffolding.
Every run leaves the repo richer than it found it. Code is only one of four outputs — the other three are what make the next run smarter. This is the "compound" in compound engineering, and the line between agentic engineering and vibe-coding.
The change itself — built to a debated plan, QA-looped, multi-lens reviewed, and verified against the running app (live browser drives, direct DB reads) before any PR opens.
Versioned requirement catalogs with permanent, immutable IDs — superseded rows tombstoned with a pointer, never deleted. Consulted at write time, checked at review gates, snapshotted at ship. Plus non-functional catalogs: security baseline, HIPAA overlay, PHI handling.
A grep-able solved-incident catalog, captured before ship and auto-applied by future planning runs. One session's debugging becomes the next session's head start — the system's failures become its rules.
Playwright tests annotated to the requirement IDs they cover, audited continuously and snapshotted at every ship — so the requirement catalog stays testable, not aspirational.
The spec machinery extends to security and compliance. I ran a STRIDE threat model on a healthcare AI product and promoted its findings into three living non-functional spec catalogs — a security baseline (secrets, auth realms, tenant isolation, transport, log hygiene), a HIPAA overlay (technical safeguards as engineering controls), and a PHI-handling catalog (the 18 identifiers; logging, URLs, proxying, retention, de-identification). Live posture gaps became a prioritized, requirement-cited, drainable backlog — each ticket mapped to the specific rule it violates and the file it lives in. The pipeline checks these catalogs at its review gates, so compliance posture is maintained by construction rather than rediscovered in the next audit.
"Concentrate judgment. Automate the span. Compound the learnings."// agentic loops & graphs — the takeaway
The discipline keeps leveling up. Prompt engineering asked "what do I say?" Context engineering asked "what does the agent know?" Loop and graph engineering asks "what does the system do while I'm not watching — and what does it leave behind?"
"Agent loops" get hyped as a prompt: point an agent at the repo, walk away, magic. What actually runs one is a dependency graph, a versioned spec, named human gates, an autonomy dial, and isolated parallel lanes. The loop is the easy part. Everything around it is the work.
Two dials, often confused. Level-3 prompting is a design-time discipline — shaping how an agent reasons before it decides, not just what it does. The autonomy dial (L0–L3) is a run-time policy — how far a pipeline may proceed without a human, with hard ceilings it cannot raise for itself. One governs the quality of agent thought; the other bounds the blast radius of agent action. You need both.
A pipeline that only produces code is a vibe. Mine produces four artifacts every run — code, specs, learnings, e2e tests — so each run leaves the repo richer than it found it. Find the bottleneck. Give the agent eyes and hands. Encode the learnings. Compound.
Designing the prompts and the systems that hold them.
CLAUDE.md · Skills · Rules · Hooks · Commands · Memory
System prompt design, evaluation suites, and full-stack context engineering across the complete Claude Code toolkit. Behavioral specs, capability modules, constraint systems, automation hooks, and persistent memory — orchestrated for reliable agent execution.
plan → work → review · file-domain isolation · JSON schema enforcement
Multi-phase workflows with subagent teams. File-domain isolation, hard tool-call and retry budgets, JSON-schema-enforced outputs, risk-driven mode selection, durable task-log contracts between phases. Registered subagents with frontmatter, restricted tools, and active-fixer contracts.
decompose → reconcile → author → tickets · immutable requirement IDs
Turning prototypes and PRDs into versioned requirement catalogs before any code: parallel-reader decomposition, reconciliation against shipped specs, permanent immutable IDs with tombstoned supersession, and requirement ↔ e2e coverage audits snapshotted at every ship.
JSON Schema · output contracts · typed disagreement
The prompt populates a schema; the schema is the artifact. JSON-schema-enforced subagent outputs make multi-agent disagreement typeable and downstream consumption parser-free.
iterative agent calibration
Converting conversation friction into persistent context. Building "compressed histories of agent failures" that evolve from project learnings.
agent failure studies · constraint design
Studying how agents fail to understand why. Converting failure patterns into behavioral constraints that prevent entire categories of errors.
steelman prompts · challenge loops
Building structured disagreement into agent workflows. Forcing agents to argue against their conclusions before presenting them — L3 behavioral engineering.
The infrastructure agents work inside of — local CLI, MCP, parallel orchestration.
slash commands · registered subagents · output design
Designing the workflows engineering teams use to ship AI features safely. Slash commands, registered subagents, output design as a first-class concern, schema-bounded contracts. The meta-tools, not the agents.
dependency graphs · computable readiness · parallel lanes · autonomy dial
Looping N parallel agent lanes over a blocked-by ticket graph until the epic drains: readiness derived from the graph, reconcile-first resume (a mid-drain context wipe costs nothing), per-slice verification tiered to risk, and an L0–L3 autonomy dial with hard ceilings the agent cannot raise.
Puppeteer · Chrome DevTools Protocol
Enabling agents to see and interact with the UI. Local CLI tools have far less overhead than MCP for autonomous debugging workflows.
port management · CDP integration
Spinning up isolated worktrees for parallel AI agents with deterministic port allocation. Agents start and work reliably by design.
Remote MCP · tool exposure
Exposing tools to agents as MCP servers. Figma Remote MCP for design integration, custom CLI tools for validation and verification.
launchd · perl · structured prompt pipelines
Health-check pipelines delivering structured notifications via launchd-scheduled diagnostics. Multi-line prompt substitution via perl + env vars. Self-locating data files for scripts deployed outside the repo. Autonomous PM-style workflows.
What ships the AI features once the agent's work is done.
React 19 · Next.js · Vite 7 · TypeScript
Building responsive and interactive user interfaces with modern React features, Next.js for optimal performance, and Vite for fast development.
FastAPI · Python 3.12 · Node.js · ASP.NET Core
Creating robust server-side applications with FastAPI microservices, async programming, and clean architecture.
asyncpg · asyncio.gather · SQLAlchemy AsyncSession · Celery
asyncpg, asyncio.gather concurrency-safety, SQLAlchemy AsyncSession lifecycle. Familiar with the asymmetries that matter in production — what SQLite tolerates that asyncpg crashes on, where Loguru silently swallows extra= kwargs, when a bound async session can and can't be shared.
PostgreSQL 16 · SQLAlchemy 2.0 · Supabase · SQL Server
Designing and implementing efficient database schemas with async ORMs, migrations (Alembic), and secure data management.
Pydantic / SQLAlchemy / FastAPI / React / TypeScript
Production root-cause work across Pydantic, SQLAlchemy, FastAPI, React, TypeScript. Multi-layer defenses for schema invariants (Alembic clamp + DB constraint + Pydantic + read-time helper). Backend/frontend parser parity (snake_case ↔ camelCase, JSON-escape normalization). Migration safety on existing rows.
Tailwind CSS 4 · Radix UI · Storybook · Figma Code Connect
Crafting beautiful and intuitive user interfaces with modern design principles, component libraries, and bidirectional design system sync.
pytest · Vitest · React Testing Library · MSW · Playwright
Comprehensive testing strategies including unit, integration, API mocking, and Playwright e2e suites annotated to requirement IDs — coverage audited against the spec catalog, not just line counts.
STRIDE · HIPAA technical safeguards · PHI handling
Threat modeling promoted into living non-functional spec catalogs — security baseline, HIPAA overlay, PHI-handling rules — enforced at the pipeline's review gates and tracked as a requirement-cited backlog. Compliance by construction, not audit archaeology.
Dispositions — how I think about engineering teams, not just code.
survey · identify · encode
Surveys other teams' prompt suites and tooling, identifies what travels and what's team-specific, encodes shared patterns into reusable tooling. The meta-skill is knowing which patterns survive contact with a different codebase.
meta-tools, not agents
Builds the meta-tools engineering teams use to ship AI features safely. Treats the SDLC itself as a product surface — multi-agent workflows, subagent contracts, output design, schema-first prompts.
decomposition before polish
Treats agent output presentation as a design decision downstream of work decomposition, not a polish layer. What the agent says is determined by how the work is broken up; the prompt's structure is the user interface.
creator's default ↔ engineer's default
Comfortable in both modes — "creator's default" (conversational, exploratory, narrating) and "engineer's default" (state machines, budgets, schemas, silence-until-result). Knows which mode each task calls for.
University of California at Riverside
// open to AI engineering roles · prompt engineering · agent orchestration