How I work
A short loop, run the same way every time, with a number at the end of it.
Six steps, and the tools each one actually uses. Hover a step, or tap it on a phone. Nothing moves forward until the step before it is done — and a change that cannot be verified goes back to step three rather than out of the door.
Every change starts as a written issue with acceptance criteria and scope boundaries. A plan that lives only in a chat window does not exist.
The main checkout stays clean and on main. Parallel work never collides, and nothing is ever committed straight to the default branch.
No placeholder that ships as though it were the real thing. If an external constraint forces a shortcut, it is called out and reverted, not left in.
The project’s real build, lint and tests — not a typecheck standing in for a build. Green means green, and “should be fine” is not a result.
An automated security and quality review gates the merge. Valid findings in scope become commits; valid findings out of scope become new issues.
A real merge commit, the branch deleted, and the issue closed with what was measured and when — so the record survives the session.
I let an agent do the work. I do not let it decide whether the work is done.
- Standing procedure, not promptsThe loop above is written down as skills the agent loads before it starts, so the same steps run whether I am watching or not.
- Delegated when it is self-containedFully specified, repo-scoped work goes to a background agent. Anything cross-cutting, architectural or ambiguous stays with me.
- The gate is machineryBuild, lint, tests and an automated review decide whether something merges. An agent saying it finished is not evidence that it did.
- Re-measure before assertingAnything that claims a system lacks a feature is re-checked live before it is repeated. A cached answer about someone else’s API is the fastest thing to go stale.
TypeScript and Python for most things. Go where a single binary and tight control of the format matter — the retrieval engine, the PDF parser and the LLM gateway are all Go. Rust and R where the work called for them.
Claude Agent SDK, Vercel AI SDK, OpenAI tools, VAPI and MCP. Claude, Gemini and GPT behind a gateway rather than wired to one provider.
Next.js App Router, server-first, with Fastify, Hono and FastAPI behind it. tRPC where the client and server are mine.
Postgres with Drizzle, on Neon or Supabase. pgvector and Qdrant where a vector index genuinely earns its place — and Vectorless where it does not.
Deepgram, ElevenLabs, YarnGPT and Twilio. Clinical-grade transcription where the words are a diagnosis rather than a caption.
Vercel, Cloudflare Workers, Docker and AWS. Whatever gets it in front of a real user soonest, then moved when the load says to move it.
| Repository | Commits | Days | What came out |
|---|---|---|---|
| enyata-project | 21 | 8 | AuraHealth, live — 21 routes, 10 tables, 5 payment APIs |
| context8 | 52 | 18 | 1.0.0 on PyPI |
| pdfgrab | 43 | 115 | v0.4.0 on the Go module proxy |
| llmgate | 30 | 153 | v0.5.0, the gateway the engine runs on |
The short spans are new products, the long ones are libraries that keep being maintained. Both are in the table because showing only the fast one would be a different claim than the true one.
This site was built the same way.
Ported from a design source by a script, verified by pixel-diffing every page against the original, and deployed from the same loop. The activity page is generated from the registries for the same reason.