[
  {
    "id": "vibe-coding",
    "title": "Vibe Coding\nwith Confidence",
    "subtitle": "The Vibecoder's Handbook, from idea to production",
    "tagline": "Build Apps That Work Beyond the Demo.",
    "description": "Plan it. Build it. Debug it. Ship it. Scale it. With AI as your engineer.",
    "author": "Mahmoud Zalt",
    "authorRole": "Principal AI Architect",
    "status": "available",
    "url": "https://zalt.me/guides/vibe-coding",
    "coverImage": "/images-optimized/blog/auto/vibe-coding-art-medium.webp",
    "edition": "2026 Edition",
    "version": "v0.1",
    "parts": [
      {
        "id": "intro",
        "title": "Introduction",
        "chapters": [
          {
            "slug": "start-here",
            "title": "Start Here",
            "label": null,
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/intro/start-here",
            "content": "---\nshare: \"Anyone can get AI to build an app in a weekend; almost nobody keeps it alive a month later. This handbook hands you the system that closes that gap: idea to live software, the AI building and you in control.\"\n---\n{/* KEEP: hook = anyone can build an app with AI, almost nobody keeps it alive; the difference is a system, not talent or code. */}\n\nAnyone can get AI to build an app in a weekend. Almost nobody can keep that app alive a month later. The difference is not talent, and it is not code. It is a system, and this book hands it to you: idea to live software, AI doing the building, you in control.\n\n{/* KEEP: pain line (breaks in ways you can't explain, not sure where anything lives) sets up the mind-map motif. Mind map = the engineer's mental picture: what pieces exist, where each fits, how they talk. AI owns the internals; reader zooms in only on sensitive areas (payments, user data, security). */}\n\n## You only need a mind map\n\nIf you have built with AI before, you know the wall: it breaks in ways you cannot explain, and you are not sure where anything even lives. Here is what nobody tells you: you do not need every line in your head, no engineer has that. You need the picture an engineer carries: what pieces your app is made of, where each one lives, and how they talk to each other.\n\nThe insides of each piece are AI's job. Yours is knowing each piece works, and zooming in only where it is sensitive: payments, user data, security.\n\n{/* KEEP: this is the book's PROMISE/solution (not a consequence of the mind map). What you walk away with: clarity of a modular layout -> confidence to add or change a feature without breaking the rest (no bug-whack-a-mole loop) -> and you stay fast because AI does the QA honestly, not rubber-stamping. This is the core payoff; frame it forward-looking. */}\n\n## Move fast, break nothing\n\nHere is what the book gives you: the clarity to lay your app out as modular pieces, so you can add or change one feature confident the rest still stands. No more the loop where every fix breaks two things you thought were done.\n\nAnd you stay fast, because AI does the checking. We show you how to put it on QA duty, testing its own work honestly instead of rubber-stamping it, so speed never costs you trust.\n\n{/* KEEP: the full lifecycle path in walk order; NOT a tutorial / prompt collection / coding course; the book covers what AI cannot decide (what to build, in what order, how to keep it alive). */}\n\n## What this is\n\nThe full path from idea to live software, in the order you actually walk it: plan it, set up, build, debug, harden, ship, operate, scale. At the end you have real software you can maintain and grow, plus a repeatable way to build the next one.\n\nIt is not a tutorial, not a prompt collection, and not a coding course. AI writes the code. This book covers what AI cannot decide for you: what to build, in what order, and how to keep it from falling apart.\n\n{/* KEEP: two readers (idea + no coding background, daily AI builder tired of fragile output); explicitly NOT for people already running production systems. */}\n\n## Who it's for, and who it's not\n\n- **You have an idea and no coding background.** You can ask AI for software, but nobody taught you how software should be built. This closes that gap.\n- **You already build with AI daily.** Speed is not your problem anymore, fragile and unmaintainable output is. This gives you a workflow designed for AI, not old habits with AI bolted on.\n\nIf you already run production systems for a living, you are not the audience. Hand this to the person who keeps asking you how.\n\n{/* KEEP: thesis = old best practices assumed humans were the bottleneck; the book's question: if you started today knowing AI exists, how would you build? Knowing which principles survive is the advantage. */}\n\n## Start from scratch\n\nMost \"best practices\" exist because humans were the bottleneck: a person typing, reviewing, and remembering every line. That world is gone, yet nearly everyone still forces AI into workflows built for it.\n\nThis book asks the only question that matters now: if you started today, knowing AI exists, how would you build software? Some old principles survive that question. Many do not. Knowing which is which is the whole advantage.\n\n{/* KEEP: app = output, the system that produces it = the real product; that system is the part nobody open-sources; the book hands it over. */}\n\n## You're building the factory, not the car\n\nThe app is the output. The real product is the system that produces it: the workflows, rules, and checks that make AI ship production-ready work every time. The car is the easy part; the factory is where the leverage lives.\n\nThat factory is the part nobody open-sources, because it is a real edge. This book hands it to you, written down, in the order you can easily follow."
          },
          {
            "slug": "how-to-read",
            "title": "How to Read it",
            "label": null,
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/intro/how-to-read",
            "content": "---\nshare: \"How to read this handbook: it runs in the exact order you build real software, each stage producing the one thing the next stage needs, so you are never stuck starting a step without what it takes to finish it.\"\n---\n{/* KEEP: this page = the manual (job 6). Concrete reader-situation lead-in (you want the lay of the land before starting), NOT the old \"most technical books are reference shelves\" meta opener. Core point: the book runs in build order, each stage feeds the next, so you're never stuck. */}\n\nBefore you build anything, you want the lay of the land: where to start, what you need, and what order to move in. This book runs in the exact sequence you build real software, each stage producing the one thing the next stage needs. Read it in order and you are never stuck starting a stage without what it takes to finish it.\n\n{/* KEEP: the one-screen map of all 10 stages, each with its concrete output in hand; output of one stage = input of the next, which is why the order matters. */}\n\n## The map: ten stages, one path\n\nEvery part of this book is one stage of a real software project, and every stage ends with something concrete in your hands:\n\n1. **Plan:** a spec your AI can build from.\n2. **Dev Set Up:** a machine and an AI agent ready to produce code.\n3. **AI Set Up:** the operating system you and your agents run everything from.\n4. **Architect:** a codebase layout your AI can extend without rewrites.\n5. **Build:** a real, running app.\n6. **Debug:** the skill to unstick your agent instead of abandoning the build.\n7. **Harden:** an app that is secure, tested, and ready for strangers.\n8. **Ship:** your software live on real infrastructure.\n9. **Operate:** a running system you can see into and keep healthy.\n10. **Scale:** growth without breaking, and knowing your limits.\n\nEach stage's output is the next stage's input. That is the whole reason the order matters.\n\n{/* KEEP: fresh-machine assumption (nothing pre-installed, set up when needed); the only two prerequisites = a computer + an AI coding agent; the agent is your teacher, the book is your judgment. */}\n\n## All you need: a computer and an agent\n\nThe book assumes a fresh machine, maybe a laptop you unboxed today. Everything else, the editor, the languages, the accounts, the hosting, gets set up exactly when you need it.\n\nTwo things before chapter one:\n\n- A computer running Windows, macOS, or Linux.\n- An AI coding agent. We help you pick one in Dev Set Up; until then, just read.\n\nYour agent is your teacher, this book is your judgment. It tells you what to ask for, in what order, and how to know the answer is good.\n\n{/* KEEP: this section = ORDER/sequence (not reading mode, that's the next section). Go through the stages in order on the first pass because each stage depends on the prior stage's output; afterward use it as a reference, jumping to the stage where you're stuck. Title must NOT clash with \"Build as you read\" (don't both say \"read\"). */}\n\n## Follow the stages in order\n\nGo through the book in order on your first pass. Because each stage needs what the last one produced, jumping ahead means starting a stage empty-handed.\n\nFrom the second visit on, use it like a manual: a deploy fails or a database buckles, go straight to that stage and skim.\n\n{/* KEEP: this is a build-along book, NOT read-only. Every chapter ends in one concrete action + copy-paste prompts (senior judgment). WHY the web/ebook version beats print: you read on the same screen as your agent, copy each prompt straight across, and build as you go; a paper copy leaves you only reading, the one thing this book is not for. Keep the agent open beside the book so the app and your understanding move together. */}\n\n## Build as you read\n\nThis is not a read-only book. Every chapter ends with one concrete thing to do, and most hand you a ready-made prompt to paste straight to your agent, loaded with the judgment a senior engineer would bring but you could not write yourself yet.\n\nThat is why the web and ebook versions beat print here. You read on the same screen as your agent, copy each prompt straight across, and build as you go. A paper copy would leave you only reading, the one thing this book is not for.\n\nSo keep your agent open beside the book. Finish a chapter and your app has moved forward, not just your understanding.\n\n{/* KEEP: the learning-in-the-AI-era philosophy + why the book is shaped this way. AI changed how you learn, so the book is deliberately SLIM: only the judgment and order that matter, no filler, covering everything a 1000-page book would; your AI supplies depth ON DEMAND (hand it a chapter, ask your own follow-ups). That's why there is NO printed/PDF version, learning is now interactive and collaborative with your AI. Plus site-only features print can't give: progress tracking, notes where they matter, one-click copy of any prompt or the whole chapter to feed your agent, discussions, and contributing edits/suggestions to the content itself. Do not cut the \"no PDF / slim on purpose / collaborative\" trio. */}\n\n## Short by design, deep on demand\n\nThis book is deliberately short. AI changed how you learn: you no longer need a thousand pages spelling out every detail, because your AI can explain any part, in your own words, the moment you ask. So we kept only the signal, the judgment and the order that actually matter, and let your AI supply the depth on demand.\n\nThat is why there is no thick PDF to print. Learning is interactive now, so the book is built to be read beside your agent: hand it a whole chapter to go deeper, then ask your own follow-up questions until it clicks for you.\n\nAnd because it lives on the page, it does what paper cannot: it tracks your progress, lets you leave notes where they matter, and copies any prompt or a full chapter in one click to feed your agent. You can also join the discussion on any chapter, and suggest edits to the content itself."
          },
          {
            "slug": "the-author",
            "title": "About the Author",
            "label": null,
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/intro/the-author",
            "content": "---\nshare: \"Every vibecoding guide has the same gap: one narrow slice, vague, or long on what and silent on why. Here is the track record behind a handbook where every move carries its reason.\"\n---\n{/* KEEP: this page = trust (job 4) + payoff (job 5). Lead-in = vibecoding handbooks are flooding out, author actually surveyed them, they share one gap (too narrow, or vague, or they say what to do but never WHY). This book's edge = the reason behind every move, which the reader has already felt reading this far. Then pivot to the track record. Do NOT regress to narrating the page's three sections. */}\n\nVibecoding handbooks are everywhere now, and more land every week. I read through what is out there, and each one has the same gap: zoomed onto a single slice, or vague, or long on what to do and silent on why. You have read this far, so you can already feel the difference here, every move carries its reason. Here is the track record behind that voice.\n\n{/* KEEP: concrete credentials: 16 years; ~100 projects built from scratch (the phrase itself links to /projects, like the OSS links below); ~another 100 managed, architected, or contributed to; 3 continents; OSS (Laradock, Apiato, Porto); Sista AI = solo-built, guides startups through AI transformation; Sistava = solo-built platform for running an entire business on AI agents. Mention for CREDIBILITY only, keep it factual and understated, not a promo/CTA (user is explicit about this). */}\n\n## I have shipped over a hundred projects\n\nMahmoud Zalt, sixteen years shipping software. Around [100 projects](/projects) built from scratch, and roughly another 100 managed, architected, or contributed to, with top teams across three continents. More on [LinkedIn](https://www.linkedin.com/in/mahmoudzalt).\n\nMore than ten open-source projects, including [Laradock](https://laradock.io), [Apiato](https://apiato.io), and [Porto](https://porto.zalt.me), tools other engineers build their own systems on. Full list on [GitHub](https://github.com/Mahmoudz).\n\nTwo companies built solo: [Sista AI](https://sista.ai), guiding startups through their AI transformation, and [Sistava.com](https://sistava.com), a platform for running an entire business on AI agents.\n\n{/* KEEP: humble + professional, do NOT criticize other teachers. Track record = 16 years building through every shift in the field; early AI adopter who went through every phase as the tools improved; with AI has shipped many products of his own and helped many others do the same (NO numbers, no \"proudest of\" style). This continuity is the credibility. */}\n\n## I adopted AI early, and kept shipping\n\nFor sixteen years I have built software, adapting through every shift the field went through. When AI coding arrived I was among the first to adopt it, and I have stayed with it through every phase, rebuilding how I work as the tools grew more capable.\n\nWith AI I have shipped many products of my own, and helped many others do the same.\n\n{/* KEEP: openly written with AI (best model available), section by section with human ordering and judgment; the onboarding-a-junior frame (if you joined my team, this is what I'd tell you). */}\n\n## AI drafted it, I ordered it\n\nThis book was written with AI, and I will say so plainly: the most capable model available at the time did the drafting. But nothing here was generated in one pass. Each section took hours of back-and-forth, pulling what I know into words and into an order a beginner can actually follow.\n\nThat ordering is the real work, and the part AI still cannot do alone. It is what I would do sitting beside a new junior on their first day: not everything at once, but the right thing next, until they can build on their own.\n\n{/* KEEP: payoff = you become a professional vibe coder (idea to live, maintained software, AI as builder); then it is practice, build real projects with AI guiding you (the thing the author never had), until you can do what a junior engineering role asks for. NO vanity counts (\"three systems\"). */}\n\n## What you walk away with\n\nYou will not write code by hand, and you will not need to. Work through this book and you become a professional vibe coder: someone who takes an idea all the way to live, maintained software, with AI doing the building.\n\nFrom there it is practice. Build real projects this way, with something I never had sixteen years ago, an AI guiding you the whole way, and before long you can do what a junior engineering role actually asks for."
          }
        ]
      },
      {
        "id": "plan",
        "title": "Structure your idea into a clear specification",
        "chapters": [
          {
            "slug": "set-up-your-workspace",
            "title": "Set Up Your Workspace",
            "label": "Workspace",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/plan/set-up-your-workspace",
            "content": "---\nshare: Set up a clean coding workspace and your AI agent on the computer you already own, before you write a single line of code.\n---\n{/* KEEP: this is the book's real first working chapter (Plan ch1). Before any step makes sense you need two things: a place to write and an AI agent (you won't type code by hand). Sets both up on the computer you already own, and leaves a specs/ folder ready for the spec written next. Absorbs the old dev-environment chapter + the old \"set up your workspace first\" section. */}\n\nBefore any step in this book makes sense, you need two things: a place to write, and something to build with. You will not type code by hand, so that something is an AI agent. This chapter sets both up on the computer you already own, and leaves you a folder ready for the spec you write next.\n\n{/* KEEP: your existing OS (Windows/macOS/Linux) is the ground floor and enough; any recent laptop works (8GB ok, 16 comfortable); buy nothing, switch nothing. Bold-first: operating system. */}\n\n## Your own computer is enough\n\nYour computer already runs Windows, macOS, or Linux. That is its **operating system**, the ground floor everything else installs onto, and any of the three builds everything in this book.\n\nAny laptop from the last few years is enough: 8 GB of memory works, 16 GB is comfortable. Buy nothing and switch nothing, you start from what you have.\n\n{/* KEEP: the one thing you cannot skip = an AI coding agent (writes and changes your code); it's the engine of the book since you don't hand-write code. Two things decide quality: the agent itself AND the model powering it, watch both. Bold-first: AI coding agent, model. */}\n\n## The agent matters more than the editor\n\nThe one thing you cannot skip is an **AI coding agent**: the program that actually writes and changes your code. Since you never type code by hand, the agent is the engine this whole book runs on.\n\nTwo things decide how good it is: the agent itself, and the **model** powering it, the AI brain it thinks with. Keep an eye on both. A sharp agent on a weak model, or the reverse, will let you down.\n\n{/* KEEP: where you work is your choice and barely matters if the agent is good. VS Code if more technical / want control; agent-first tools (Claude Code, Codex, Cursor, OpenCode) if you want the simplest path. New ones appear constantly, ask or search for the current best, pick what you're comfortable in. What matters = agent + model, not the interface. Do NOT prescribe only VS Code. */}\n\n## Pick where you work\n\nWhere you and the agent work together is your choice, and it matters far less than the agent itself.\n\n- **More technical, or want full control?** Install [VS Code](https://code.visualstudio.com), a free editor from Microsoft, and run your agent inside it.\n- **Want the simplest path?** Use an agent-first tool like [Claude Code](https://claude.com/claude-code), [Codex](https://developers.openai.com/codex), [Cursor](https://cursor.com), or [OpenCode](https://opencode.ai), where the agent is the whole interface.\n\nNew options appear all the time. Ask your agent or search for the current best, then pick the one you feel comfortable in. What matters is the agent and its model, not the shell around them.\n\n{/* KEEP: the model is the brain the agent runs on, and most agents let you SWAP it. Frontier models (closed, big labs: Claude/GPT/Gemini/Grok) = most capable for hard reasoning/code; open-source models (Llama/DeepSeek/Qwen/GLM) = cheaper, self-hostable, catching up fast. Rankings change constantly, no permanent winner, check a live leaderboard (LMArena, Artificial Analysis), never trust last year's. The move: pick an agent that lets you switch models, re-check every few months, never lock into one vendor. Ends with a Hint callout: OpenRouter = one account/bill/interface to switch models; open-source can also run locally but needs serious hardware. Links: vendors + leaderboards + OpenRouter. Do NOT re-bold \"model\" (bolded earlier); bold-first: frontier, open-source. */}\n\n## Never lock into one model\n\nYour agent runs on a model, and most agents let you swap that model out. Two camps are worth knowing:\n\n- **Frontier** models, like [Claude](https://claude.com), [GPT](https://openai.com), [Gemini](https://gemini.google.com), and [Grok](https://grok.com), are the most capable. They are closed, run by the big labs, and best for hard reasoning and tricky code.\n- **Open-source** models, like [Llama](https://llama.com), [DeepSeek](https://deepseek.com), [Qwen](https://qwen.ai), and [GLM](https://z.ai), you can run cheaply or host yourself, and they are closing the gap fast.\n\nWhich model leads changes every few weeks, so no ranking you read today stays true for long. Do not trust last year's winner: check a live leaderboard like [LMArena](https://lmarena.ai) or [Artificial Analysis](https://artificialanalysis.ai) when the choice matters.\n\nThe move is to stay loose. Pick an agent that lets you switch models, and re-check every few months. That way you are never stuck with one vendor, and you always ride the current best.\n\n> **Hint:** [OpenRouter](https://openrouter.ai) gives you most models through one account, one bill, and one interface, so you switch between them without signing up with each vendor. Open-source models you can also run on your own machine, but that takes serious hardware to run a capable one well.\n\n{/* KEEP: create one project folder + a specs/ folder inside so the NEXT chapters have somewhere to write the spec. Full project layout waits until you know the app's pieces; a specs folder is all you need to start. */}\n\n## Make a folder, and a home for your spec\n\nCreate one new folder on your computer for this project; it will hold everything you build. Inside it, add a folder named `specs` for your planning notes. That is your whole workspace today.\n\nThe full project layout waits until you know your app's pieces. A `specs` folder is all you need to start writing, which is the very next thing you do.\n\n{/* KEEP: one setup prompt (senior voice, fixed top + one append slot) that recommends an agent + interface for THIS reader and walks the install + folder creation. Ends with Do this now. */}\n\n## Set it all up in one pass\n\nThis prompt has your agent recommend the right tools for you and walk you through the whole setup:\n\n```\nAct as a patient senior engineer setting someone up to\nbuild software with AI for the first time. Based on my\ncomputer and how technical I am, recommend an AI coding\nagent and where to run it: a plain editor like VS Code, or\nan agent-first tool. Then walk me, step by step, through\ninstalling it, creating a project folder with a folder\nnamed specs inside, and checking it all works.\n\nMy computer and experience:\n```\n\n**Do this now:** set up your agent and editor, create your project folder with a `specs` folder inside, and open it once so you have seen your workspace."
          },
          {
            "slug": "gathering-requirements",
            "title": "Turning an Idea Into a List",
            "label": "Requirements",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/plan/gathering-requirements",
            "content": "---\nshare: Your AI agent cannot build a feeling, and you cannot check whether a feeling is finished. Turn the idea in your head into a clear, testable list of what the software must do, before any code.\n---\nYou have the whole idea in your head. Your agent cannot build a feeling, and you cannot check whether a feeling is finished. Before any code, you turn that idea into a clear, specific list of what the software must do. This chapter gets you that list.\n\n## A requirement is testable, not a wish\n\nA **requirement** is one thing your software must do, written plainly enough that anyone can tell whether it works yet.\n\n| Wish | Requirement |\n|---|---|\n| Users can log in | A person signs in with an email and password, and resets a forgotten one through an email link |\n\nThe difference is that you can test the requirement and point at a clear yes or no. Write every requirement so it passes that test.\n\n## Write each one as a user story\n\nProfessional teams capture requirements as **user stories**, one line each: `As a [type of user], I want to [do something], so that [reason].` It forces you to name who the feature is for and why it exists, which quietly kills the features nobody actually needs.\n\n> **Example:** As a shopper, I want to save items to a cart, so that I can pay for them all at once.\n\n## Split must-have from later\n\nList every story you can think of, then mark each one **must-have** or **later**. Be harsh: a must-have is something the product is useless without, not something that would be nice to have. The must-haves are all you build first; everything else waits its turn.\n\n## Get them from real users, not your head\n\nRequirements come from the people who will actually use the thing, not your imagination. Talk to three to five real potential users and write down what they ask for in their own words.\n\n> **Watch out:** if you cannot find one person who wants this, that is the cheapest moment you will ever get to learn it, long before you have built anything. Check before you build; if you build anyway, at least know you skipped it.\n\nThis prompt turns the idea in your head into that list:\n\n```\nAct as a senior product engineer. Interview me about the\napp I want, then turn my idea into user stories, one line\neach: \"As a [user], I want [action], so that [reason].\"\nMark each must-have or later, and keep every one testable,\nsomething we can point at and call done. Save the list in\nmy specs folder.\n\nMy idea:\n```\n\n**Do this now:** paste the prompt, describe your idea, and let your agent draft the user-story list into your `specs` folder. That list is the raw material for every chapter that follows."
          },
          {
            "slug": "scoping-your-mvp",
            "title": "Cutting Scope to the Core",
            "label": "MVP",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/plan/scoping-your-mvp",
            "content": "---\nshare: \"Every item on your must-have list feels essential, which is exactly why it will sink your first version. Cut it down to an MVP: the smallest thing you can ship that actually helps one real person.\"\n---\nYour must-have list is still too big. Every item on it feels essential, which is exactly why the list will sink your first version if you try to build all of it. This chapter cuts that list down to an MVP: the smallest thing you can ship that actually helps one real person.\n\n## An MVP is the smallest version worth shipping\n\n**MVP** stands for **minimum viable product**. It is the leanest version of your idea that still delivers real value to one kind of user and can go live.\n\nTwo words carry the weight. \"Minimum\" means you cut ruthlessly. \"Viable\" means what is left still works for someone, end to end, on its own.\n\n## Apply the one core job test\n\nEvery product exists to do one core job. For everything on your list, ask a single question: does this feature directly serve that one job, or does it just decorate it?\n\n| Product | The one core job |\n|---|---|\n| A note app | Write a note and find it again |\n| A store | Buy one item and pay |\n| A booking tool | Reserve one slot at one time |\n\nIf a feature is not required for that core job to work once, it is not in the MVP. It can be the best idea you have and still wait.\n\n## Expect to cut some must-haves too\n\nHere is the uncomfortable part: some features you marked must-have in the previous chapter still get pushed to a later version. \"Must-have eventually\" and \"must-have to ship the first slice\" are different bars.\n\n| In the MVP | Pushed to later |\n|---|---|\n| Sign in with email | Sign in with Google, Apple |\n| Post one item for sale | Bulk upload, drafts, scheduling |\n| Pay with one card | Saved cards, refunds, coupons |\n| One language | Translations |\n\n## Build a walking skeleton, not half an app\n\nA **walking skeleton** is one thin path through your whole app that actually works: a user arrives, does the core job once, and gets a result. It is skinny, but every bone connects.\n\nThis beats building many features to fifty percent. Ten half-finished features ship nothing a person can use. One complete path, however plain, is a product you can put in front of someone tomorrow.\n\n## Guard the line against scope creep\n\n**Scope creep** is the slow drift of \"while we are at it, let us also...\" that turns a two-week build into a six-month one. Every added feature feels small in the moment and enormous in total.\n\nWrite your MVP list down and treat new ideas as a separate \"later\" pile, not an edit to the plan. The plan is closed; the pile stays open.\n\n> **Example:** An MVP for a food-delivery app: one restaurant, a fixed menu, one delivery address, pay with one card. No search, no ratings, no live tracking. A hungry person can still order dinner, so it is viable.\n\nThis prompt cuts your list to the core for you:\n\n```\nAct as a senior engineer scoping my MVP. From my user\nstories, find the single core job the app exists to do,\nthen keep only the stories needed to do that job once, end\nto end. Challenge every must-have: if the product still\nworks without it, move it to later. List what ships now and\nwhat waits.\n\nMy user stories:\n```\n\n**Do this now:** paste the prompt with your stories, and let your agent cut them to the smallest version that does the one core job, moving the rest to a \"later\" pile."
          },
          {
            "slug": "the-pieces-of-an-app",
            "title": "The Pieces of an App",
            "label": "Components",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/plan/the-pieces-of-an-app",
            "content": "---\nshare: Every web app is a few standard parts, each with its own job. Learn to name the five pieces and follow a single click through them, so you can tell your agent what to change and reason about why things break.\n---\nYour idea feels like one thing, but every web app is made of a few standard parts, each with a separate job. If you cannot name those parts, you cannot tell your agent which one to change, and you cannot reason about why something broke. This chapter gives you that map: the five pieces and how a single click travels through them.\n\n## The five pieces\n\nEvery web app is built from the same handful of parts. Learn these names once and the rest of the handbook stops sounding foreign.\n\n| Piece | What it does |\n|---|---|\n| Frontend | What the user sees and clicks in the browser: the pages, buttons, forms |\n| Backend | The server that runs your logic: it decides what happens when a request arrives |\n| Database | Where data is stored so it survives after the browser closes |\n| API | The agreed set of messages the frontend and backend use to talk to each other |\n| Hosting | The computers where all of the above actually run, reachable over the internet |\n\n## Frontend and backend are two programs\n\nThe **frontend** runs on the user's device, inside their browser. The **backend** runs somewhere else, on a server you control, out of the user's reach.\n\nThis split matters because anything secret (passwords, private data, business rules) lives in the backend, never the frontend. The frontend is public by nature: anyone can open it and look.\n\n## The API is a contract, not a place\n\nThe frontend cannot reach into the database directly. It sends a request to the backend through the **API**, a fixed list of allowed messages like \"give me this user's orders\" or \"save this comment.\"\n\nThink of the API as a menu. The frontend can only order dishes on the menu, and the backend decides how each one is cooked.\n\n## The database remembers, hosting runs it\n\nThe **database** is the app's memory. Close the browser, restart the server, and whatever was saved there is still waiting.\n\n**Hosting** is simply the rented computers where the frontend, backend, and database live so the public can reach them. Which specific tools fill each slot is a later decision, covered when you choose your stack.\n\n## Trace one click through all five\n\nFollow one action, a user saving a comment, and watch it cross every piece in order:\n\n1. **Frontend:** packages the typed comment and sends it off.\n2. **API:** carries that request to the backend as an agreed message.\n3. **Backend:** checks the user is allowed, then writes the comment down.\n4. **Database:** stores it and confirms it is saved.\n5. **Frontend again:** shows the saved comment on screen.\n\nAll of it runs on **hosting**, the rented computers underneath.\n\nEvery feature you build is some version of this loop. Once you can see the loop, a bug stops being \"the app is broken\" and becomes \"which piece dropped the message.\"\n\nThis prompt maps your app onto the five pieces:\n\n```\nAct as a senior engineer. Map my app onto the five pieces\nof a web app: frontend, backend, API, database, and\nhosting. For each, say in one line what it does for my app\nspecifically. Then trace one core feature as a round trip\nthrough all five.\n\nMy app:\n```\n\n**Do this now:** paste the prompt and let your agent map your five pieces, then read the round trip so you can picture where each feature lives."
          },
          {
            "slug": "modeling-your-data",
            "title": "Mapping What You Store",
            "label": "Data Model",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/plan/modeling-your-data",
            "content": "---\nshare: \"Code changes cheaply; the shape of your stored data does not, once real users have filled it. Sketch a plain data model first: the things you store, what each holds, and how they connect.\"\n---\nYour app stores things: people, their stuff, the records of what they did. Code changes cheaply, but the shape of that stored data does not, because once real users have created it, you cannot rename or reorganize it without touching everything they made. So you sketch that shape first, on paper, before a line of code. This chapter gets you a plain data model: the things you store, what each one holds, and how they connect.\n\n## The shape of your data is called a schema\n\nA **schema** is the plan for what your app stores, separate from the place it gets stored (an earlier chapter covered what a database is). You are drawing the plan now, not choosing the storage yet.\n\nThe plan has two parts: the things you keep, and the links between them. Get both right on paper and the actual build is mostly transcription.\n\n## List your entities and their key fields\n\nAn **entity** is one kind of thing you store, like a `User` or an `Order`. A **field** is one piece of information an entity holds, like a user's email or an order's total.\n\nName each entity as a singular noun, then list only its key fields: the ones the app genuinely needs, not every detail you can imagine. Write it as a plain table.\n\n| Entity | Key fields |\n|---|---|\n| `User` | `name`, `email`, `password` |\n| `Order` | `total`, `status`, `createdAt` |\n\nIf you cannot name an entity as a single noun, it is probably two entities hiding in one.\n\n## Draw the relationships between them\n\nA **relationship** is how two entities connect. Most connections are **one-to-many**: one entity owns many of another, and each of those belongs to exactly one owner.\n\nA `User` has many `Orders`, and each `Order` belongs to one `User`. That is one-to-many. When both sides have many (a `Post` has many `Tags` and a `Tag` covers many `Posts`), that is **many-to-many**, and you note it as such.\n\nState every relationship in that plain \"has many\" and \"belongs to\" form. Sketched out, a shop's model nests like this:\n\n```\nUser\n  has many: Order\n    has many: LineItem\n      references: Product\n```\n\nEach indent is a \"belongs to\": a `LineItem` sits under one `Order`, which sits under one `User`. It reads unambiguously to both you and your agent, no diagram tool needed.\n\n## Keep it a sketch, not a database\n\nResist writing SQL, picking a product, or adding fields for features you have not scoped. The model is a thinking tool, and every field you add now is one more thing to keep true later.\n\nA later chapter turns this sketch into real tables. Right now you only need it clear enough that someone else could read it and know what your app remembers.\n\nThis prompt drafts the sketch from your app:\n\n```\nAct as a senior engineer sketching my data model. From my\napp, list the entities (the things it stores), each with\nits key fields, and state every relationship as \"has many\"\nor \"belongs to.\" Keep it a plain sketch, not SQL and not a\nreal database yet.\n\nMy app, and what it needs to remember:\n```\n\n**Do this now:** paste the prompt and let your agent draft the entity sketch, then check the relationships match how you picture your app."
          },
          {
            "slug": "non-functional-requirements",
            "title": "The Hidden Requirements",
            "label": "NFRs",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/plan/non-functional-requirements",
            "content": "---\nshare: Your features say what the software does, not how fast, reliable, or safe it must be. Pin down these quality targets early, while changing them is still cheap, because they quietly decide your architecture and stack.\n---\n{/* KEEP: lead-in = user stories say WHAT it does, not HOW WELL (fast/reliable/for how many). Those quality bars = non-functional requirements: the part most tutorials and books SKIP, and the part serious engineers pin down EARLY, because they decide architecture and stack before any feature exists. This chapter = a short list of measurable targets set now, while changing them is still cheap. */}\n\nYour user stories say what the software does. They say nothing about how well it has to do it: how fast, how reliably, how safely, for how many people. Those quality bars are non-functional requirements, the part most tutorials skip and serious engineers pin down early, because they quietly decide your architecture and stack long before you write a single feature. This chapter gets you a short list of measurable targets, set now, while changing them is still cheap.\n\n{/* KEEP: functional requirement = a thing the software does; non-functional requirement = a standard it must meet while doing it. Table contrasts the two sides. Bold-first: functional requirement, non-functional requirement. */}\n\n## What it does vs. how well it does it\n\nA **functional requirement** is a thing the software does. A **non-functional requirement** is a standard it must meet while doing it.\n\n| Functional | Non-functional |\n|---|---|\n| A shopper can pay for a cart | Checkout completes in under 3 seconds |\n| A user uploads a photo | The site handles 500 people uploading at once |\n| An admin views a report | The report is available 99.9% of the time |\n\nThe functional side is the feature. The non-functional side is the quality bar that feature is held to.\n\n{/* KEEP: targets must be NUMBERS, not adjectives (\"fast\"/\"secure\" can't be tested). Walk five categories (performance, availability, security, scale, accessibility) and turn each vague wish into a measurable target. Three-column table: category | vague | measurable. */}\n\n## Set a number, never an adjective\n\n\"Fast\" and \"secure\" cannot be tested. A number can. Every target you write should be something you or your agent can measure and get a clear yes or no on.\n\nWalk these five categories. For each, turn the vague wish into a number a test can check:\n\n| Category | Vague (won't do) | Measurable target |\n|---|---|---|\n| Performance | \"fast\" | A page loads in under 2 seconds |\n| Availability | \"reliable\" | Up 99.9% of the time |\n| Security | \"secure\" | Passwords encrypted, login enforced on private data |\n| Scale | \"handles growth\" | 10,000 users and 1 GB of data in year one |\n| Accessibility | \"usable by all\" | Works by keyboard and screen reader, meets [WCAG](https://www.w3.org/WAI/standards-guidelines/wcag/) AA |\n\n{/* KEEP: THE most important idea of the chapter, hammer it. Your OBJECTIVE (raw speed vs tight accuracy vs a target user count) decides how the whole app is architected. Document these targets and hand them to the AI BEFORE it designs anything, so it builds the structure to hit them; leave them out and it guesses wrong and you pay to redo the foundation. Not built here, a later part covers hitting the bars. */}\n\n## Write them down for your AI before it builds\n\nThese are not paperwork, they are the most important thing you decide in this part. Your objective, whether you need raw speed, tight accuracy, or a set number of users, decides how the whole app is put together.\n\nA \"handle 500 uploads at once\" target changes your database and hosting from day one. Bolt scale or accessibility on after launch and you are usually rewriting the foundation.\n\nHand these targets to your AI before it designs anything, and it builds the structure to hit them. You are not implementing any of it yet, a later part covers how. Here you just set the bars, so every choice downstream has something to aim at.\n\n> **Example:** 95% of pages load in under 2 seconds on a mobile connection, and the app is available 99.9% of the time.\n\nThis prompt proposes your targets, tuned to your goal:\n\n```\nAct as a senior engineer setting my non-functional targets.\nFor my app, propose one measurable target in each of:\nperformance, availability, security, scale, accessibility.\nEvery target must be a number a test could check, and must\nfit my real objective, not generic best practice. Save them\nin my specs folder.\n\nMy app, and my main objective (speed, accuracy, scale...):\n```\n\n**Do this now:** paste the prompt with your objective, let your agent propose the five measurable targets into your `specs` folder, and adjust any number that does not match your goal."
          },
          {
            "slug": "writing-the-spec",
            "title": "Writing It All Down",
            "label": "Spec",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/plan/writing-the-spec",
            "content": "---\nshare: Your requirements, scope, parts, data, and quality targets are useless scattered across notes. Assemble them into one short spec, the single document your AI agent actually builds from.\n---\nThe earlier chapters each left you with a piece: user stories, a scope line, the app's parts, its data, its non-functional targets. Scattered across notes and your head, those pieces are useless to an agent that reads before it builds. This chapter assembles them into one short document, the spec, that your agent works from.\n\n## A spec is a document your agent builds from\n\nA **spec** is a single short document describing what the software must be and do. If you have heard the term **PRD**, short for product requirements document, that is the same idea under a heavier name.\n\nYour agent needs it as its single source of truth: the one thing it reads before building, so it does not guess and invent details you never wanted. Without it, every ambiguity becomes a coin flip you did not get to call.\n\n## Short and living, not forty pages\n\nA spec is not an exhaustive contract you write once and freeze. It is a working document you keep tight and update as you learn.\n\n| Forty-page document | Living spec |\n|---|---|\n| Written once, out of date by week two | Edited whenever scope or data changes |\n| Covers every edge case up front | Covers the shape; details emerge in the build |\n| Nobody rereads it | Short enough to reread before each task |\n\nAim for something you and the agent can both hold in your head. A page or two beats a chapter nobody keeps current.\n\n## Assemble the sections you already have\n\nEach section maps to a Plan chapter you already worked through. You are not writing new material here, you are collecting it.\n\n- **Problem and audience:** the problem and who it is for.\n- **Scope:** the MVP as must-have user stories.\n- **Main pieces:** the app's components and its modular shape.\n- **Data model:** the entities and how they relate.\n- **Non-functional targets:** speed, security, and scale you committed to.\n\n> **Template:**\n> ```\n> # [Product name]\n> ## Problem & audience\n> ## Scope (MVP user stories)\n> ## Main pieces & structure\n> ## Data model\n> ## Non-functional targets\n> ```\n\n## Keep it in the repo, next to the code\n\nPut the spec in the project itself, its **repo** (the folder that holds all your code), as a plain [markdown](https://commonmark.org) file the agent can open every time. A spec living in a chat window or a separate doc is one your agent cannot reliably read.\n\nKeeping it beside the code means every edit to scope or data lands in the same place the build happens. The spec and the software drift apart the moment they live in different homes.\n\nThis prompt assembles the spec from what you already wrote:\n\n```\nAct as a senior engineer assembling my spec. Pull the\npieces I already have (user stories, MVP scope, the five\ncomponents, the data model, the non-functional targets)\ninto one short spec.md in my specs folder. Keep it tight\nand skimmable, a living document, not forty pages.\n\nMy pieces (paste them, or point to the files in specs):\n```\n\n**Do this now:** paste the prompt, point your agent at your `specs` folder, and let it assemble `spec.md`. A later chapter turns this spec into instructions your agent builds from."
          }
        ]
      },
      {
        "id": "setup",
        "title": "Prepare your environment and tools",
        "chapters": [
          {
            "slug": "choosing-your-stack",
            "title": "Picking Your Tech Stack",
            "label": "Stack",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/setup/choosing-your-stack",
            "content": "---\nshare: Ignore the hundreds of options and the fights about them. Get a solid tech stack to start on today, plus a prompt that picks the right one for your case with a senior engineer judgment.\n---\nYou have a workspace and a spec. Now you choose what to build the app out of: the language, the framework, the database, the place it runs. Ignore the hundreds of options and the fights about them. This chapter hands you a stack to start on today, and a prompt that picks the right one for your case with a senior engineer's judgment.\n\n## A stack is layers, bottom to top\n\nA **stack** is just the layers your app is built from, each sitting on the one below:\n\n- **Platform:** where it runs, web, iPhone, or desktop. This choice decides everything above it.\n- **Language:** the code it is written in, like [TypeScript](https://www.typescriptlang.org) or [Python](https://www.python.org).\n- **Framework:** a proven structure on top of the language, so you do not start from a blank page.\n- **Boilerplate:** a ready-made starter project, so you begin from a working app instead of an empty folder.\n- **Libraries:** open-source pieces you drop in for one specific job instead of building it yourself.\n\nYou pick from the bottom up, and at each layer the popular choice is usually the right one.\n\n## Default to the popular choice\n\nPick the most common option unless a hard requirement forces otherwise. Your agent has built it countless times and makes fewer mistakes with it, so popularity is really how much help you get.\n\n## A stack for almost any app\n\nFor a typical web or consumer app, take this as-is:\n\n| Piece | Use | Why |\n|---|---|---|\n| Frontend | [React](https://react.dev), via [Next.js](https://nextjs.org) | The default way to build a web interface |\n| Backend | [Node](https://nodejs.org) with TypeScript | Same language as the frontend, one stack to run |\n| Database | [PostgreSQL](https://www.postgresql.org) | Proven, free, handles almost anything |\n| Hosting | A plain rented server | Cheapest and simplest; a plain server suits your agent better than a fancy dashboard |\n\nOne language front to back. Next.js can serve both sides, so it is often the whole stack on its own.\n\n## Switch when the job demands it\n\nThe default holds until your app has a real requirement. Then a senior engineer moves deliberately, one line each:\n\n- **AI or heavy data:** a Python backend, its ecosystem is years ahead.\n- **Very low latency or high throughput:** [Go](https://go.dev) or [Rust](https://www.rust-lang.org) on the hot path.\n- **A static or brochure site:** no backend or database at all.\n\n## Let your agent choose for your case\n\nThis prompt already carries the engineering judgment. Paste it in and describe your app in the one slot at the bottom, nothing in the middle to hunt down and replace:\n\n```\nAct as a senior engineer choosing my stack. Recommend a\nfrontend, backend, database, and hosting for the app below.\nDefault to the simplest, most popular, agent-friendly option,\nand override only where my case demands, with real\nengineering judgment:\n\n- Typical web or consumer app: TypeScript everywhere.\n- AI or heavy-data app: Python backend for the ecosystem.\n- Low-latency or high-throughput core: Go or Rust there.\n- Weigh ecosystem maturity, hosting cost, and how easily\n  an agent can maintain it.\n\nFor each choice: one line of reasoning, plus one alternative\nand its tradeoff.\n\nMy app:\n```\n\n**Do this now:** take the default stack, or paste the prompt and describe your app at the bottom, then lock one tool into each piece before the next chapter."
          },
          {
            "slug": "meet-your-ai-agent",
            "title": "Meeting Your AI",
            "label": "Agent",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/setup/meet-your-ai-agent",
            "content": "---\nshare: Your AI agent is not a chatbot that answers questions, it reads your files, runs commands, and changes your code. Knowing what it can and cannot do, and where its limits are, is what separates steering it from hoping.\n---\n{/* KEEP: lead-in = you picked an agent in Workspace; now understand what it actually IS so you can steer it instead of hope. Not tool-picking (that's Plan ch1), this is the mental model of working with an agent. */}\n\nYou already picked an agent back when you set up your workspace. Now you need to understand what it actually is, because the difference between steering it and just hoping comes down to knowing how it works. This chapter gives you that mental model.\n\n{/* KEEP: an agent is NOT a chatbot that just answers; it reads your files, runs commands, writes and changes code, and checks its own results, in a loop, inside your project. It acts, it doesn't just talk. Bold-first: agent. */}\n\n## What an agent actually is\n\nAn **agent** is not a chatbot that answers questions. It reads the files in your project, runs commands, writes and changes code, sees what happened, and goes again, in a loop, until the task is done.\n\nThat is the whole shift: a chatbot talks, an agent acts. It works inside your actual project, on your actual files, which is why everything in this book is about directing that action well.\n\n{/* KEEP: what it CAN do (write/refactor/wire features/fix errors/explain code fast) vs what it CAN'T (know your intent, decide what's worth building, judge good-enough, own the consequences). It is astonishing at the how, blind to the whether/why. That gap is the reader's job. */}\n\n## What it can and can't do\n\n| It's brilliant at | It cannot |\n|---|---|\n| writing and refactoring code | know what you actually want |\n| wiring up a feature | decide what's worth building |\n| reading an error and fixing it | judge when it's good enough to ship |\n| explaining a strange file in seconds | own the consequences |\n\nGive it a clear task and it outruns any human at the typing. But it is brilliant at the *how* and blind to the *whether* and the *why*, and that gap is exactly your job.\n\n{/* KEEP: agents work from CONTEXT (what's in front of them right now: open files, your message, what it just read), NOT long-term memory; it forgets between sessions. So you must feed it the right context each time; the rules file and a clear spec are how you make the important context always present (forward-points to the Rules chapter without naming mechanics). Bold-first: context. */}\n\n## It works from context, not memory\n\nAn agent works from **context**: what is in front of it right now, your message, the files it has open, what it just read. It does not carry a memory of your project between sessions the way a teammate would. Close it, reopen it, and it starts fresh.\n\nSo getting good work out of it is mostly getting the right things in front of it at the right moment. Much of this book, the spec you wrote, the rules you will set next, exists to keep the context that matters always in view.\n\n{/* KEEP: trust it to TYPE, not to DECIDE. Let it produce code fast, but you own the decisions (what to build, whether the result is right, what ships). Read what it does, don't rubber-stamp. This sets up code review later without naming it. */}\n\n## Trust it to type, not to decide\n\nLet the agent do the typing, all of it, at full speed. That is what it is for, and second-guessing every line wastes the whole advantage.\n\nBut keep the decisions yours: what to build, whether the result is actually right, what is allowed to ship. Read what it produces instead of waving it through. The agent is the fastest pair of hands you will ever have, and you are still the one steering.\n\n**Do this now:** open your agent and ask it to explain one file in your project out loud, so you see how it reads context and works, before you start directing it for real."
          },
          {
            "slug": "agent-rules",
            "title": "Setting the Ground Rules",
            "label": "Rules",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/setup/agent-rules",
            "content": "---\nshare: An agent forgets everything between sessions, so it repeats the same mistakes. A rules file is your standing instructions it reads every time, the difference between correcting it forever and telling it once.\n---\n{/* KEEP: lead-in = an agent starts fresh every session (context, not memory, from the last chapter), so it repeats the same mistakes. A rules file = standing instructions read automatically every time. Chapter = write it once instead of correcting forever. */}\n\nYour agent starts every session fresh, so it repeats the same mistakes: wrong folder, wrong style, a library you already rejected. Correcting it each time is exhausting and it never sticks. This chapter gives you the fix, a rules file the agent reads automatically, every single time.\n\n{/* KEEP [pro]: a rules file = a plain text file of standing instructions the agent reads at the start of every session, on its own. It is how you turn \"context, not memory\" (last chapter) into consistency: the important context is always present without you re-typing it. Bold-first: rules file. */}\n\n## A rules file is your standing instructions\n\nA **rules file** is a plain text file of standing instructions your agent reads at the start of every session, without being asked. It is how you beat the memory problem from the last chapter: the things that matter are in front of the agent every time, so you never re-type them.\n\nThink of it as onboarding a new hire who arrives with amnesia each morning. The rules file is the one-page brief that makes them productive again in seconds.\n\n{/* KEEP [pro]: put the NON-NEGOTIABLES in writing = the decisions you never want re-litigated: the stack, where code goes, the naming style, libraries to prefer or avoid, commit habits, \"always run the app before saying done\". Concrete, testable instructions, not vague vibes. */}\n\n## Put the non-negotiables in writing\n\nFill it with the decisions you never want to explain twice: your stack, where new code goes, the naming style, which libraries to prefer or avoid, how to commit, \"always run the app before telling me it works.\"\n\nWrite them concrete, the way you would tell a person, not as vague vibes.\n\n| Vague | Concrete rule |\n|---|---|\n| \"write clean code\" | \"keep files under 300 lines, one feature per folder\" |\n| \"be careful with secrets\" | \"never hardcode keys, keep them out of the code\" |\n| \"test your work\" | \"run the app and confirm it works before saying done\" |\n\n{/* KEEP: keep it SHORT and LIVING = a bloated rules file gets ignored (by you and the agent); keep it tight. It is living: every time you correct the agent on something it should have known, add that as a rule so you never correct it again. */}\n\n## Keep it short and living\n\nA giant rules file gets skimmed and ignored, by the agent and by you. Keep it tight, only the rules that actually matter.\n\nAnd keep it living. Every time you catch yourself correcting the agent on something it should have known, add that as one line. Over a few weeks the file quietly becomes the exact brief your project needs.\n\n{/* KEEP: where it lives = in the project itself (in the repo, alongside the code), so it travels with the code and every agent on the project reads the same rules. Each tool has its own filename/location, so let the agent set it up for your tool. Ends with Do this now = have the agent create the rules file for your tool + seed it. */}\n\n## Where the file lives\n\nThe rules file lives inside your project, committed alongside the code, so it travels with the repo and every agent that opens the project reads the same rules. Each tool looks for it under its own name and place, so the simplest move is to let your agent create the right one for the tool you chose.\n\nThis prompt has your agent create its own rules file:\n\n```\nAct as a senior engineer configuring my agent. Create the\nrules file for the tool I use, in the right filename and\nplace, and seed it with: my stack, where new code goes, my\nnaming style, and a few non-negotiables (for example: run\nthe app and confirm it works before telling me it's done).\nKeep it short.\n\nMy tool and stack:\n```\n\n**Do this now:** paste the prompt so your agent creates the rules file, then read it and add one rule you already know you care about. Add to it every time you correct the same thing twice."
          },
          {
            "slug": "version-control",
            "title": "Never Losing Work",
            "label": "Version Control",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/setup/version-control",
            "content": "---\nshare: You are about to let AI change your code all day. Version control is the safety net so one bad change never buries the version that worked, plus the words to make your AI use it right.\n---\n{/* KEEP: lead-in = you're about to let AI change code all day; without a safety net one bad change buries the working version. Version control is the net; this chapter gives the net + the vocabulary to make sure AI uses it right. */}\n\nYou are about to let AI change your code all day long. Without a safety net, one bad change can bury the version that worked, with no way back. Version control is that net, and this chapter hands it to you along with the words to make sure your AI uses it right.\n\n{/* KEEP: define git plainly = saves a snapshot (commit) of the whole project every time something works; you can return to any of them; the repo is the folder git watches. Unlike editor undo, git never forgets and never runs out. Bold-first: git, commit, repo. */}\n\n## Git is your undo button\n\n[**Git**](https://git-scm.com) is a tool that saves a snapshot of your whole project every time something works. Each snapshot is a **commit**, and you can jump back to any of them, so a version that ran is never more than one step away. The folder git watches is your **repo**, short for repository.\n\nUnlike the undo in a text editor, git never forgets and never runs out. Months of commits stay there, each one a safe place to return to.\n\n{/* KEEP: reassurance = you do NOT memorize or type git; the agent runs every command. Your job is judgment, knowing what should happen so you can tell it's being done right. That is the whole point of the chapter. */}\n\n## Your AI runs git, not you\n\nHere is the relief: you will not memorize a single git command. Your agent runs every one of them for you.\n\nWhat you need is not the typing, it is the judgment: knowing what should be happening, so you can tell when it is being done right. That is all this chapter is for.\n\n{/* KEEP: branch = a private copy split from the main line where AI tries a feature; merge if it works, throw it away if it breaks and main is untouched. Worktrees = one-line mention (several branches at once), AI handles them, reader doesn't. Bold-first: branch, main, worktrees. */}\n\n## Every experiment gets its own branch\n\nWhen AI tries a new feature, it should do it on a **branch**: a private copy of the project split off from the main line. If the feature works, the branch is merged back in. If it breaks, you throw the branch away and the working version, the **main** branch, never felt it.\n\nYou may also hear about [**worktrees**](https://git-scm.com/docs/git-worktree), a way to keep several branches open at once. Same idea, and your agent handles it. You do not need to.\n\n{/* KEEP: the one habit = commit after each small working change, not one giant commit at the end. Small commits = precise undo (undo the one bad step, not an afternoon). Instruction to give the agent: commit often with a short message. */}\n\n## Commit after every working step\n\nOne habit matters more than the rest: have your agent commit after each small change that works, never one giant commit at the end.\n\nSmall commits are precise. When something breaks, you undo the one step that caused it instead of losing an afternoon of work.\n\n> **Rule of thumb:** if it runs and does one new thing, commit it.\n\n{/* KEEP: semantic versioning = three numbers major.minor.patch (e.g. 2.4.1); major = breaking, minor = new feature, patch = fix. WHY START EARLY (the point of this section): versioning from day one gives you a clear marker for big changes/refactors, lets you control deployments and know exactly which version is live, and makes future debugging easier (you can pinpoint which version introduced a bug). Start now at ~0.1.0. Reader doesn't calculate it, tells AI to follow it. Bold-first: semantic versioning. Table for the three parts. */}\n\n## Version numbers that tell the truth\n\nWhen you share software, its version number tells people what changed. The standard is [**semantic versioning**](https://semver.org): three numbers like 2.4.1, each with a job.\n\n| Number | Goes up when | Example |\n| --- | --- | --- |\n| Major | a change breaks how it worked before | 1.9 to 2.0.0 |\n| Minor | you add a feature, nothing breaks | 2.3 to 2.4.0 |\n| Patch | you fix a bug | 2.4.0 to 2.4.1 |\n\nStart numbering from your very first working version, not once things get serious. With versions in place you always know where you stand: which one is live, what changed since, and, when a bug appears, which version introduced it. That one early habit makes big refactors, deployments, and debugging far easier later.\n\nYou do not work the numbers out yourself. Tell your agent to follow semantic versioning from the first release, starting around 0.1.0, and your history stays honest about what changed.\n\n{/* KEEP: the setup prompt (senior-engineer voice, fixed content + one append slot). Sets the agent's git ground rules once: commit per working step with clear messages, branch per feature, semantic versioning. Ends with Do this now = paste it. */}\n\n## Set the git rules once\n\nGive your agent these rules at the start, and it handles version control for the whole project:\n\n```\nAct as a senior engineer managing version control for\nmy project. From now on, without me asking each time:\n- Commit after every change that works, with a short,\n  clear message saying what changed.\n- Put each new feature on its own branch, and merge it\n  back only once it works.\n- Follow semantic versioning for releases: major for a\n  breaking change, minor for a feature, patch for a fix.\nExplain what you are doing the first few times so I can\nfollow along.\n\nMy project:\n```\n\n**Do this now:** paste the prompt above to your agent, so version control is running before you write another line."
          },
          {
            "slug": "dependencies",
            "title": "Living on Other People's Code",
            "label": "Dependencies",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/setup/dependencies",
            "content": "---\nshare: Almost everything your app needs, login, payments, dates, file uploads, is already built and battle-tested by millions. Learn to lean on these dependencies without inheriting their problems.\n---\n{/* KEEP: lead-in = don't build from scratch; almost everything (login, payments, dates, uploads) already exists as dependencies, tested by millions. Chapter = how to lean on them without inheriting their problems. */}\n\nYou could tell your AI to write everything from scratch. You should not. Almost everything your app needs, login, payments, date handling, file uploads, someone has already built and millions have tested. These ready-made pieces are dependencies, and this chapter shows you how to lean on them without inheriting their problems.\n\n{/* KEEP: dependency = code someone else wrote that your app installs and uses (a library / package); the agent installs them and lists them in one manifest file so any machine rebuilds the exact set; reader never installs by hand, their job is deciding which to trust since each is code they can't fully see. Bold-first: dependency, library, package, manifest. */}\n\n## What a dependency actually is\n\nA **dependency** is code someone else wrote that your app installs and uses, usually called a **library** or a **package**. Rather than build a payment flow or a calendar yourself, you pull in one that already works, hardened by everyone who uses it.\n\nYour agent installs them and lists them in one file, the **manifest** (like `package.json`), so any machine can rebuild the exact same set. You never install them by hand. Your job is deciding which are worth trusting, because each one is code you cannot fully see.\n\n{/* KEEP: choosing = prefer widely-used, recently-updated, still-maintained libraries; popularity means bugs surface fast, recent activity means security holes get patched. And add one only when it saves real work; for a few lines let the agent just write them (fewer deps = smaller surface to trust). Rule-of-thumb callout. */}\n\n## Pick popular, maintained, and alive\n\nNot every library deserves your trust. Before your agent adds one, it should prefer the option that is widely used, recently updated, and still maintained. Popularity means bugs surface fast; recent activity means security holes get patched.\n\nAdd one only when it saves real work, too. For a handful of lines, have your agent just write them, every dependency you skip is one less thing that can break on you.\n\n> **Rule of thumb:** a library with thousands of users and a commit this month beats a slicker one nobody has touched in two years.\n\n{/* KEEP: updating = old deps are where security problems pile up, so keep them current; but an update can change behavior, so update in small batches and check the app still works after each, never update everything at once right before shipping. Do NOT use \"branch\"/\"tests\" here (forward refs to version-control and Harden). */}\n\n## Update often, but never blindly\n\nOld dependencies are where security problems quietly pile up, so keep them current. An update can also change how a library behaves, though, so it pays to update a few at a time and check the app still works after each batch.\n\nWhat you never do is update everything at once the day before you ship. Small, checked steps let you catch the one update that broke something while it is still easy to find.\n\n{/* KEEP: version conflicts = two libs can want different versions of a third, or an update silently pulls in a newer piece that breaks yours; the lockfile (agent creates it automatically) records the exact version of everything so the app builds identically everywhere and nothing shifts unseen. Agent resolves conflicts; reader's job = notice when something that worked stops working. Bold-first: lockfile. */}\n\n## Lock versions so builds stay identical\n\nLibraries depend on other libraries, so two of them can want different versions of a third, or a fresh install can pull in a newer piece that breaks yours. Those version numbers follow a shared convention, [semantic versioning](https://semver.org), so a jump in the first number warns you a change may break things. A **lockfile**, which your agent creates automatically, records the exact version of everything, so the app builds the same on every machine and nothing shifts under you unseen.\n\nWhen versions do conflict, your agent sorts it out. Your job is only to notice when something that worked yesterday suddenly does not, and point the agent at it.\n\n{/* KEEP: license = every library ships with a license (legal terms for using it); most popular ones (MIT, Apache) allow almost anything, a few (some GPL variants) put conditions on how you distribute your own code. Rarely bites a small project, but before building a business on a library have the agent confirm its license is one you can live with. Link: choosealicense.com. Bold-first: license. */}\n\n## Check the license before you build on it\n\nEvery library comes with a **license**, the legal terms for using it. Most popular ones, like MIT and Apache, let you do almost anything. A few, like some GPL variants, put conditions on how you share your own code.\n\nIt rarely bites a small project, but before you build a business on a library, have your agent confirm its license is one you can live with. [choosealicense.com](https://choosealicense.com) explains the common ones in plain language.\n\n**Do this now:** ask your agent to list every dependency your project already pulls in, with each one's popularity, last update, and license, so you know exactly what you are standing on."
          },
          {
            "slug": "secrets-and-config",
            "title": "Handling Keys and Config",
            "label": "Secrets",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/setup/secrets-and-config",
            "content": "---\nshare: Put one password or API key in your code, and the day you share that code you hand strangers the keys. Keep every secret out of your codebase from the start with a git-ignored .env file.\n---\n{/* KEEP: lead-in = your app needs passwords/keys to reach its database, payments, AI services; put even one in the code and sharing the code hands strangers the keys. Chapter = keep every secret out of the codebase from day one. */}\n\nYour app needs passwords and keys to reach its database, its payment provider, its AI services. Put even one of those in your code, and the day you share that code, push it, or paste it to your agent, you hand strangers the keys. This chapter keeps every secret out of your codebase from the start.\n\n{/* KEEP: secret = any value that lets someone act as you/your app (db password, API key, payment token, signing key); if leaking it costs money or access, it's a secret. Everything else (titles, feature flags) = plain config, safe to share. Bold-first: secret, config. */}\n\n## What counts as a secret\n\nA **secret** is any value that lets someone act as you or your app: a database password, an API key, a payment token, an auth signing key. The test is simple: if leaking it costs you money or access, it is a secret.\n\nEverything else is just **config**, plain settings like a page title or a feature switch. Config is safe to share; secrets never are. This chapter is about the secrets.\n\n{/* KEEP [pro]: the rule pros never break = a secret is NEVER written in the code itself, because code gets shared, pushed, copied, pasted to the agent, and a hardcoded key travels everywhere the code goes. Secrets live OUTSIDE the code, in environment variables the app reads by name. Bold-first: environment variable. */}\n\n## Keys never touch the code\n\nThe rule a professional never breaks: a secret is never written in the code itself. Code gets shared, pushed to your repo, copied between machines, pasted to your agent, and a key sitting inside it travels to every one of those places.\n\nInstead, secrets live outside the code, in **environment variables**: values the app reads from its surroundings at startup, by name. The code says \"give me the database password,\" never the password itself.\n\n{/* KEEP: the .env file = standard home for secrets, KEY=value per line, read at startup; NEVER committed, add it to .gitignore. Commit a .env.example with the same keys but blank/fake values so others know which keys exist without seeing them. version-control already taught (this chapter comes after), so commit/repo/.gitignore are fine here. Bold-first: .env, .gitignore, .env.example. */}\n\n## One .env file, never committed\n\nThe standard home for those values is a file named **.env** in your project, one `KEY=value` per line, that your code reads when it starts. This file never leaves your machine: you add it to your **.gitignore** so version control skips it and it is never committed.\n\nSo anyone else, including your future self, knows which keys exist without seeing their values, you commit a **.env.example** beside it: the same key names with blank or fake values. The real secrets stay local, the list of what is needed is shared.\n\n{/* KEEP: if a secret ever leaks (screenshot, commit, pasted log), treat it as burned and ROTATE it: generate a new key at the provider, replace the old one, which instantly makes the leaked one useless. Do it immediately. Watch-out: a secret pushed to a repo stays in git history even after you delete it, rotating is the only real fix. Bold-first: rotate. */}\n\n## Rotate anything that leaks\n\nIf a secret ever slips out, in a screenshot, a commit, a pasted log, treat it as burned. **Rotate** it: generate a fresh key at the provider and replace the old one, which instantly makes the leaked copy useless. Do it the moment you notice, not later.\n\n> **Watch out:** a secret pushed to your repo does not disappear when you delete the line, it stays in the history. Rotating the key is the only real fix.\n\n{/* KEEP: prompt (senior voice) to wire up secret handling for the reader's stack: create .env, add to .gitignore, create .env.example, move existing keys out of code into .env and read from there. Ends with Do this now. */}\n\n## Wire it up for your stack\n\nThis prompt has your agent set secret handling up correctly for whatever stack you chose:\n\n```\nAct as a senior engineer setting up secret handling for\nmy project. Create a .env file for my stack and add it to\n.gitignore so it is never committed. Create a .env.example\nwith the same keys but empty values. Move any keys already\nsitting in my code into .env and read them from there.\nTell me what each key is for.\n\nMy stack:\n```\n\n**Do this now:** move every key out of your code into a git-ignored `.env`, and commit a `.env.example` beside it so the list of needed keys is shared but the values are not."
          }
        ]
      },
      {
        "id": "ai-os",
        "title": "Setup your AI agents operating system",
        "chapters": [
          {
            "slug": "os-first",
            "title": "System Comes Before the Code",
            "label": "OS-First",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/ai-os/os-first",
            "content": "---\nshare: The instinct after setup is to start building the app. The people who win with AI build the system that runs everything first, then the app is just one thing that system produces.\n---\n{/* KEEP: lead-in = after setup the instinct is to start the app; instead build the SYSTEM that runs everything first (the factory metaphor from Start Here, now taught not just framed). This part builds that system. */}\n\nYou are set up, and the instinct is to start building the app right now. Hold on. The people who get the most out of AI build the system that runs everything first, and then the app is just one of the things that system produces. This chapter is why, and the rest of this part builds it with you.\n\n{/* KEEP: concept = the factory-before-car idea from the intro, now concrete. The system is a set of folders and files your agents work inside: plans, decisions, progress, and the rules everything runs by. It is the factory; the app is one car it makes. Ends with a one-line forward point to unified-system (where the factory lives); do NOT re-teach \"one tree\" here. */}\n\n## The factory before the car\n\nIn the introduction you saw the idea: the app is the car, and the system that produces it is the factory. This part is where you actually build that factory.\n\nThe factory is not abstract. It is a set of plain folders and files on your computer that hold your plans, your decisions, your progress, and the rules your agents work by. The app is just one of the things it produces. Where that factory lives, one tree that holds everything, is the next chapter.\n\n{/* KEEP: build the system BEFORE the app. Jumping straight to app code = building the car with no factory: every feature a one-off, nothing compounds. Build the system first and every later task drops into a place that already exists, with rules and context already set. Plus the practiced-sequence line: add machinery only when a real task hurts without it, the system earns each part. */}\n\n## Build the system before the app\n\nMost people open the editor and start generating app code on day one. That is building the car with no factory: every feature is a one-off, and nothing you do makes the next thing easier.\n\nBuild the system first and it flips. Every task after it, a feature, a fix, a marketing push, drops into a place that already exists, with the rules and the context already set.\n\nThis is a practiced sequence, not a slogan. The people who run real operations this way add each piece of machinery only when a task hurts without it, so the system earns every part it carries and never hauls dead weight.\n\n{/* KEEP: the system is a one-time setup that pays forever. Once it exists the agents have a home: they know where things go, the current priorities, and how you want work done. You stop re-explaining and start commanding. Rest of the part builds it piece by piece. Do this now = create the one folder that will be your operating base, separate from any single app's code. */}\n\n## Build it once, it keeps producing\n\nThe system is set up once and pays off forever. When it exists, your agents have a home: they know where things go, what matters right now, and how you want the work done. You stop re-explaining yourself and start giving commands.\n\nThe proof is never glamorous. In one long-running setup, a single plain file describing how the deploy really works ended a mistake the agent had repeated in every session; that one page paid for the whole system inside a week.\n\nThe rest of this part builds it one piece at a time: one unified tree, folders that act as departments, a control center you steer from, agents configured to work your way.\n\n**Do this now:** create one new folder that will be your operating base, kept separate from any single app's code. It stays empty for now; the next chapters fill it in."
          },
          {
            "slug": "unified-system",
            "title": "One System for Everything",
            "label": "Unification",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/ai-os/unified-system",
            "content": "---\nshare: Your plans are in one app, your tasks in another, your notes in a third, and your agent can see none of them. Put the whole operation in one tree of plain files the agent can actually read.\n---\n{/* KEEP: lead-in = your operation is scattered across apps (Notion/Trello/head) and the agent sees none of it. This chapter puts everything in one tree of plain files the agent can read and write. */}\n\nYour plans live in one app, your tasks in another, your notes in a third, and your agent can open none of them. This chapter puts your whole operation into one tree of plain files on your machine, so nothing that runs your work is hidden from the thing doing it.\n\n{/* KEEP: one tree, not ten apps. Everything (plans, tasks, notes, decisions, the app) lives in one folder tree; NOT Notion for docs, Trello for tasks, chat for decisions. Reason: the agent can open a folder, it cannot open your Notion or your memory. Show a small folder-tree sketch (device variety, os-first was all prose). */}\n\n## One tree, not ten apps\n\nEverything about your operation lives in one folder tree on your machine: your plans, your tasks, your notes, your decisions, and the app itself. Not a docs app, a task app, and a chat thread each holding a piece.\n\nThe reason is blunt: your agent can open a folder. It cannot open your Notion, your task app, or your memory of what you decided last Tuesday.\n\n```\noperating-base/\n  plans/\n    roadmap.md\n  tasks/\n    todo.md\n  decisions.md\n  app/            (your actual application code)\n```\n\nThat is day one. A production tree grows branches you will build through this part: reports the agents write, skills they load, a log of everything that happened.\n\n{/* KEEP: everything is a plain file (usually markdown = plain text with light formatting), not a proprietary format locked in an app. A plan, a task list, a decision = a plain text file the agent reads and writes natively, and that you can still open in ten years. Gloss markdown (new term). Bold-first: markdown. */}\n\n## Everything is a plain file\n\nEvery piece is a plain text file, usually [**markdown**](https://commonmark.org), which is just plain text with light formatting. Not a document locked inside some app's format.\n\nA plan is a text file. A task list is a text file. A decision is one line in a text file. That is exactly what your agent reads and writes on its own, and what you can still open in ten years when today's apps are gone.\n\n> **Hint:** some people formalize this into a shared convention so every agent reads a knowledge base the same way, like the [Open Knowledge Format](https://okf.md) (markdown files plus a few frontmatter rules). You do not need a spec to start, but it is a useful reference once your tree grows.\n\n{/* KEEP: one source of truth. Because it's one tree, each thing lives in exactly ONE place; the current priorities are one file, not remembered three ways. Change it there and every agent reading it sees the truth. No syncing, no \"which version is right\". */}\n\n## One source of truth\n\nBecause it is all one tree, each thing lives in exactly one place. Your current priorities are one file, not three half-remembered versions in your head and two apps.\n\nWhen something changes, you change it there. Every agent that reads it then sees the same truth, with no syncing and no \"which copy is right.\"\n\n{/* KEEP: why one beats many. Ten apps = ten silos the agent can't cross + a picture only you can assemble in your head. One tree = the agent sees the whole thing, moves work between parts, nothing hidden. Also it's YOURS: plain files on your disk, portable, backed up with your code, not locked in someone's cloud. */}\n\n## Why one system beats many\n\nTen apps mean ten silos your agent cannot cross, and a full picture only you can hold, in your head. One tree means the agent sees everything, moves work between the parts, and misses nothing.\n\nIt is also yours. Plain files on your own disk are portable, backed up alongside your code, and never locked inside someone else's cloud.\n\n**Do this now:** pick one thing you currently track in another app, your task list or your notes, and move it into a plain text file inside your operating base. That is the first file of your system."
          },
          {
            "slug": "departments-and-folders",
            "title": "Folders as an Org Chart",
            "label": "Departments",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/ai-os/departments-and-folders",
            "content": "---\nshare: Every operation is already an org chart, you just have to make the folders match it. Draw the company as directories and anyone, human or agent, understands it in ten seconds.\n---\n{/* KEEP: lead-in = your work is many kinds of thing scattered with no place an agent knows to look. This chapter turns the operation into folders, an org chart on disk you and your agents read the same way. */}\n\nYour operation is a dozen different kinds of work, scattered across apps and your head, with no place an agent knows to look. This chapter turns it into folders: an org chart on disk that you and your agents read the exact same way.\n\n{/* KEEP: draw the company as directories before any automation (marketing, sales, money, customers, ops); the whiteboard tree = the on-disk tree, so the structure of the work and the structure of the files are the same. Anyone who opens it understands the operation in ten seconds. Show a folder-tree sketch. */}\n\n## Folders are your org chart\n\nBefore you write a line of automation, draw your operation as directories. Marketing, sales, money, customers, ops: each box on the whiteboard becomes a folder in your operating base.\n\n```\noperating-base/\n  marketing/\n  sales/\n  customers/\n  money/\n  ops/\n  app/          (the product itself)\n```\n\nNow the structure of the work and the structure of the files are the same thing, and anyone who opens the tree, you or an agent, understands the operation in ten seconds.\n\n{/* KEEP: organize by FUNCTION, not by tool or file type. No \"spreadsheets\"/\"docs\" folders; one sales/ folder holds everything sales whatever the format. High cohesion inside, clean seams between: an agent working sales opens one folder and finds its whole world. */}\n\n## One folder per function\n\nOrganize by function, never by tool or file type. You do not want a spreadsheets folder and a docs folder; you want a `sales/` folder that holds everything sales, whatever the format.\n\nHigh cohesion inside each folder, clean seams between them. When an agent works on sales, it opens one folder and finds the whole world it needs, and nothing leaks across the walls.\n\n{/* KEEP: each folder gets ONE control file, a status file (call it _status.md), holding three things: the department's rules, its current state, and a running log. It's the surface an agent reads to work and writes to record what it did. You never hunt for a department's truth. Show a minimal _status.md skeleton. Bold-first: status file. */}\n\n## Each department runs from one status file\n\nEvery folder gets a single control file, a **status file**, call it `_status.md`. It holds three things: the rules for that department, its current state, and a running log.\n\n```\n# Sales - status\n\n## Rules\n- Never promise a date we have not agreed internally.\n\n## Current state\n- 3 live deals, 1 in contract.\n\n## Log\n- 2026-07-08: sent the Acme proposal.\n```\n\nIt is the one surface an agent reads to do the work and writes to record what it did. The rule is standing: any agent that works in a department appends a dated line to its Log before it finishes, so you never hunt for the truth of a department. Later, your briefing command reads these files to build the one-screen picture, which is why keeping them honest pays off.\n\n{/* KEEP: start with the departments you HAVE, not the dream company. Three folders is fine. Add a department the day a real function appears, not before. The org chart grows as the operation grows, one folder at a time, never carrying rooms nobody lives in. Do this now = create one folder per function you run today + an empty _status.md in each. */}\n\n## Start with the departments you have\n\nDo not model the company you dream of. Model the one that exists today. Three folders is a fine start.\n\nYou add a department the day a real function appears, not before. The org chart grows the way the operation grows, one folder at a time, and it never carries rooms nobody lives in.\n\nThis prompt has your agent build the tree for you:\n\n```\nAct as a senior engineer setting up my operating system.\nIn my operating base, create one folder per function I run,\nand put an empty _status.md in each, with three headings:\nRules, Current state, Log. Do not invent functions I did\nnot name.\n\nThe functions I run today:\n```\n\n**Do this now:** paste the prompt above and list the functions you actually run, so your agent builds the department tree for you."
          },
          {
            "slug": "control-center",
            "title": "Your Command Hub",
            "label": "Control Center",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/ai-os/control-center",
            "content": "---\nshare: \"Ten departments running at once pull you in ten directions. Build one room you steer from: a cockpit above every folder where you see the whole operation on one screen and decide what matters.\"\n---\n{/* KEEP: lead-in = many departments running at once pull you ten directions. This chapter builds the one room you steer from: a cockpit above every folder where you see the whole operation on one screen and decide what matters. */}\n\nTen departments running at once will pull you in ten directions. This chapter builds the one room you steer from: a cockpit that sits above every folder, where you see the whole operation on one screen and decide what matters this week.\n\n{/* KEEP: create ONE top-level cockpit folder above every department; it does no work, it points at the work. From here you see everything and decide. Every other folder is an employee, this one is your desk. Show the cockpit tree. Bold-first: cockpit. */}\n\n## One hub steers it all\n\nCreate a single top-level folder, the **cockpit**, that sits above every department. Give it an obvious name so it sorts to the top:\n\n```\noperating-base/\n  _control/\n    planner.md      (what we're doing right now)\n    decisions.md    (every call, with the reason)\n    todos/          (the priority list)\n  marketing/\n  sales/\n  ...\n```\n\nIt does no work. It points at the work. Every other folder is an employee; this one is your desk, and it is where you stand to run everything.\n\n{/* KEEP: the heart of the hub = one planning file answering \"what are we doing right now\" (focus, roadmap, the few numbers that matter, money). Agents read it to prioritize, you read it to remember what you decided. When everything feels urgent, this file makes one thing win. Shown as a real artifact (planner.md sketch). todos/ glossed = the committed work the plan produces. */}\n\n## Set the current focus and priorities\n\nThe heart of the cockpit is one planning file that answers a single question: what are we actually doing right now.\n\n```\n# Planner\n\n## Focus (this week)\n- Get the first 10 paying users.\n\n## Roadmap\n- Now: onboarding emails. Next: pricing page test.\n\n## Numbers\n- 41 signups, 6 paying, $174 MRR.\n```\n\nAgents read it to know what to prioritize when they have a choice. You read it to remember what you decided. When everything feels urgent, this one file is what makes a single thing win. The `todos/` folder next to it holds the committed work the plan produces, each task one small file.\n\n{/* KEEP: decision log = every meaningful call gets ONE line, newest first, with the reason (why a feature is on, why this price, why that channel died). Stops you AND the agents relitigating the same call monthly and silently reversing past choices. The log is the operation's memory of its own judgment. Show decisions.md lines. Bold-first: decision log. */}\n\n## Keep a decision log\n\nEvery meaningful call gets one line in a **decision log**, newest first, with the reason attached:\n\n```\n# Decisions (newest first)\n\n- 2026-07-08: Price at $29/mo, not $19. Room to discount later.\n- 2026-07-06: Dropped the LinkedIn channel. No signups in 6 weeks.\n```\n\nThis is not bureaucracy. It is what stops you and your agents from relitigating the same decision every month, or quietly reversing a choice you made for a reason you have since forgotten.\n\n{/* KEEP: the point of the hub = a single entry point, one command that pulls the state of every area into one briefing and shows what needs you. You don't visit ten folders, you run one command, read one screen, act. Forward-points softly to Reporting (commands built there); gloss, don't teach mechanics. Do this now = create the cockpit with a planner file + decisions log, write today's focus + one recent decision. */}\n\n## Drive it with one command\n\nThe whole point of the cockpit is that it can be read in one move. It is laid out so a single command can pull the state of every area into one briefing, instead of you opening ten folders by hand.\n\nIn a running system that briefing has a fixed shape: the numbers that moved, what landed since you last looked, and the decisions waiting on you. You build that command later, when you set up reporting. For now, know that the cockpit is the thing it reads: one screen in, one decision out.\n\nThis prompt stands up the whole cockpit for you:\n\n```\nAct as a senior engineer setting up my operating system.\nAt the top of my operating base, create a _control folder\nwith: planner.md (my focus, roadmap, key numbers, money),\ndecisions.md (a dated log, newest first, each line with its\nreason), and a todos/ folder. Seed planner.md from what I\ntell you below.\n\nMy focus and top priorities right now:\n```\n\n**Do this now:** paste the prompt and describe your current focus, so your agent builds the cockpit and seeds it."
          },
          {
            "slug": "configuring-agents",
            "title": "Standing Up Your Agents",
            "label": "Configuration",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/ai-os/configuring-agents",
            "content": "---\nshare: An agent with no configuration is a stranger who shows up every morning having forgotten the job. Configuration is a file that hands it the job description before it starts.\n---\n{/* KEEP: lead-in = an unconfigured agent is a stranger who forgot the job daily. Configuration = a file that hands it the job description before it starts. You set your project rules earlier; here you define a specific agent's role. CODE-FORWARD chapter. */}\n\nAn agent with no configuration is a stranger who shows up every morning having forgotten the job. Configuration is the file that hands it the job description before it starts. You already wrote your project's rules; this chapter defines a specific agent with a role of its own.\n\n{/* KEEP: a role is a FILE, not a paragraph you paste. Show the real shape: frontmatter (name, description, tools allowed) + standing instructions. A coworker defined in version control, not a mood set each session. Bold-first: role. */}\n\n## Give each agent a role\n\nA **role** is a small file, not a paragraph you retype into chat each time. In Claude Code it lives in `.claude/agents/`, and every serious tool has the same idea: a [YAML](https://yaml.org) frontmatter block plus instructions.\n\n```\n---\nname: reviewer\ndescription: Reviews code after it's written. Use before any commit.\ntools: Read, Grep, Glob\n---\nYou review for correctness, security, and style. You do not\nwrite features and you do not refactor. Report issues by\nseverity, then stop. A hardcoded secret is a blocking issue.\n```\n\nThat is a coworker defined in a file your project keeps, not a mood you set and lose each session.\n\n{/* KEEP: a role carries two attachments, kept as SEPARATE composable files: skills = procedures loaded only when the task needs them; rules = hard lines, always on. Show the folder layout. Don't pour everything into one giant prompt. Bold-first: skill, rule. */}\n\n## Skills and rules per agent\n\nA role carries two kinds of attachment, and you keep them as separate files so they compose. A **skill** is a procedure loaded only when the task needs it. A **rule** is a hard line, always on.\n\n```\n.claude/\n  agents/reviewer.md         (the role)\n  skills/security-review.md  (loaded when reviewing auth code)\n  rules/no-secrets.md        (always on, every turn)\n```\n\nThat layout is Claude Code's; every serious tool has an equivalent folder. You never pour all of it into one giant prompt. You attach the right skill to the right role and let the rest stay out of the way until it is needed.\n\n{/* KEEP: unconfigured agents DRIFT (same request, different shape Monday vs Friday); a rule file pins the shape. Show a real rules/output.md. The quality bar lives in a file, not in your memory of how you asked. */}\n\n## Configuration keeps output consistent\n\nUnconfigured agents drift: the same request gives a different shape of answer on Monday and Friday. A rule file pins the shape:\n\n```\n# rules/output.md\n- Answer in bullets, never a wall of text.\n- Back every claim about the system with a command you ran.\n- No \"should be\" or \"probably\". Check, then state.\n```\n\nNow the quality bar lives in a file, not in your memory of how you happened to ask last time.\n\n{/* KEEP: configuration is an ASSET, not a per-task chore. The role defined today serves every task that agent runs; the rule written once fires on every future turn. An hour standing an agent up right pays back on every job after. Config is committed alongside the code it governs. Do this now = create one role file for a job you repeat (a reviewer). */}\n\n## Write it once, reuse everywhere\n\nConfiguration is an asset, not a chore. The role you define today serves every task that agent ever runs, and the rule you write once fires on every future turn.\n\nAn hour spent standing an agent up correctly pays back on every job it does after. You are not configuring a task, you are configuring an employee, and the file is committed alongside the code it governs.\n\nThis prompt has your agent write its own role file, in your tool's format:\n\n```\nAct as a senior engineer configuring my agents. Create a\nrole file for a reviewer agent, in the format my tool uses:\nfrontmatter with name, description, and the minimum tools it\nneeds, then standing instructions to review for correctness,\nsecurity, and style and then stop, treating a hardcoded\nsecret as a blocking issue. Keep it short.\n\nMy tool and project:\n```\n\n**Do this now:** paste the prompt so your agent writes the reviewer role file, then read it and tighten one line yourself."
          },
          {
            "slug": "agent-memory",
            "title": "What the Agent Remembers",
            "label": "Memory",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/ai-os/agent-memory",
            "content": "---\nshare: \"Agents are brilliant and amnesiac, they forget your whole world between sessions. A memory file fixes the amnesia: one file the agent reads at the start of every session so you never re-explain.\"\n---\n{/* KEEP: lead-in = agents forget everything between sessions; a memory file is one file the agent auto-reads at session start so it walks in already knowing your world. You met the idea as a rules file (Part 2); this is the real per-tool file + the discipline that keeps it useful. CODE-FORWARD. */}\n\nAgents are brilliant and amnesiac. Close one and reopen it, and your project, your rules, your whole world are gone. A memory file fixes that: one file the agent reads automatically at the start of every session, so it walks in already knowing the room instead of asking you again.\n\n{/* KEEP: the concept, tightened (you met it as the rules file in Part 2). The memory file holds what is ALWAYS true: who you are, how you work, the project, what must never happen. Show a real CLAUDE.md-style example. It's the constitution, not the encyclopedia. */}\n\n## The file your agent reads first\n\nYou met this idea as your rules file. The **memory file** is that file, made real for each tool: it holds what is always true, who you are, how you work, what must never happen, in a few lines the agent reads before it does anything.\n\n```\n# Project: my-app\n\n- Stack: Next.js + Postgres. One language, TypeScript.\n- New code goes under src/, one folder per feature.\n- Never commit secrets. Read them from .env.\n- Run the app and confirm it works before saying done.\n```\n\nKeep it the constitution, not the encyclopedia: the standing law, not every detail.\n\n{/* KEEP: every serious tool has ONE always-loaded file; name the real ones (swappable). Table: tool -> file. The lesson: find yours and set it up first, not as an afterthought. Real tools named + linked. */}\n\n## Find your tool's file\n\nEvery serious agent tool auto-reads one file. Same idea, different name:\n\n| Tool | File it reads |\n| --- | --- |\n| [Claude Code](https://claude.com/claude-code) | `CLAUDE.md` at the repo root |\n| [Codex](https://developers.openai.com/codex) | `AGENTS.md` at the repo root |\n| [Cursor](https://cursor.com) and most editors | a rules file or `.cursor/rules/` folder |\n\nFind yours and treat it as the first thing you set up, not an afterthought. Any equivalent works; the file changes, the idea does not.\n\nThere is now a shared convention for this, [AGENTS.md](https://agents.md), a single file over 30 tools read the same way. If your tool supports it, one file covers most of them at once.\n\n{/* KEEP: plug-in pattern = for an agent with NO native memory file, keep one canonical file yourself and inject it at session start (by hand or a tiny wrapper). Mechanism varies, principle holds: the standing truth reaches the agent before it acts. */}\n\n## No built-in file? Inject it yourself\n\nIf your agent has no native memory file, you build the behavior. Keep one canonical file, `context.md`, and paste it (or have a tiny wrapper prepend it) at the start of each session.\n\nThe mechanism does not matter. The principle does: the standing truth of your project reaches the agent before it does anything else.\n\n{/* KEEP: keep it short = every line is re-sent every turn, so bloat costs on every request forever. Cap it, push topical detail into skills loaded on demand, fix a line the day a fact changes. The MEMORY.md index: one line per durable fact, detail in linked files. */}\n\n## Keep it short, or it rots\n\nEvery line of a memory file is re-sent on every turn, so bloat is a tax you pay forever, on requests that never even touch the topic. Keep it brutally short: only what must be true always. Push topical detail into skills the agent loads on demand.\n\nThis is measured, not a hunch. Studies across thousands of projects put the useful ceiling around 150 lines; past that, the file stops helping and quietly raises cost by roughly a fifth. If yours is longer, it is doing too much.\n\nFor facts that pile up, keep an index instead of a wall:\n\n```\n# MEMORY.md\n- Auth: we use email + magic link. Details in auth/notes.md.\n- Billing: Stripe, test mode until launch. See money/stripe.md.\n```\n\nOne line per durable fact, the detail in a linked file. Fix any line the day the fact changes; a short current file beats a long stale one every time.\n\n{/* KEEP: how memory gets WRITTEN, not just read. Don't hand-maintain it: tell the agent to save the fact when you correct it, so the file grows itself. But two disciplines or it rots: one fact per file/line, and a recalled memory that names a file or flag is a hint to VERIFY against live reality, never a fact to act on (old memory = old documentation). */}\n\n## Let the agent write it, but verify what it recalls\n\nYou do not maintain this by hand. When you correct the agent, tell it to save the correction, and the file grows itself: session 1 you fix a mistake, session 40 it never repeats because the note loads every time.\n\nTwo disciplines keep it from rotting. One fact per line, deduped. And a recalled line that names a file or a setting is a hint to check, never a fact to trust: a note written months ago can point at something since renamed. Treat old memory like old documentation, verify against reality before acting on it.\n\n{/* KEEP: prompt = have the agent create the right memory file for the reader's tool, seeded from their project, kept short. Ends with Do this now. */}\n\n## Set up your memory file\n\nThis prompt has your agent create the right file for your tool:\n\n```\nAct as a senior engineer setting up my agent's memory.\nFind the memory file my tool auto-reads (CLAUDE.md,\nAGENTS.md, or a rules file), create it at the right place,\nand seed it with my stack, where code goes, and my\nnon-negotiables. Keep it short, only what must be true\nevery session. Put topical detail in separate files.\n\nMy tool and project:\n```\n\n**Do this now:** paste the prompt so your agent writes its own memory file, then read it and cut any line that is not true on every single session."
          },
          {
            "slug": "agent-tools",
            "title": "Connecting Your Agent to the World",
            "label": "Tools",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/ai-os/agent-tools",
            "content": "---\nshare: \"A model with no tools can only think and talk. Tools are how it reaches out and touches the real world: your database, your browser, your repo, your accounts, so it checks instead of guessing.\"\n---\n{/* KEEP: lead-in = a model with no tools can only think and talk; tools let it touch the real world (database, browser, repo, accounts) so it checks instead of guessing. CODE-FORWARD. */}\n\nA model with no tools can only think and talk. Tools are how it reaches out and touches the real world: your database, your browser, your repository, your accounts. With them, the agent stops guessing and starts checking.\n\n{/* KEEP: MCP (Model Context Protocol) = the standard plug for connecting an agent to an external system; register a server in config, the agent gains real actions. Show the MCP JSON config. Real tools named + swappable. Bold-first: MCP. Link: modelcontextprotocol.io. */}\n\n## What MCP is\n\n**MCP** (the Model Context Protocol) is the standard plug for connecting an agent to an outside system. You register a server in a config file and the agent gains a set of real actions, one adapter shape for every integration instead of hand-wiring each:\n\n```\n{\n  \"mcpServers\": {\n    \"postgres\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@modelcontextprotocol/server-postgres\",\n               \"postgresql://localhost/app\"]\n    }\n  }\n}\n```\n\nClaude Code reads this from an `.mcp.json` file; most tools read something like it. The servers are swappable; the plug is the same. See [modelcontextprotocol.io](https://modelcontextprotocol.io).\n\n{/* KEEP: with connections wired the agent stops guessing and starts checking: queries the live DB instead of assuming a number, drives a real browser to test a page, opens PRs on GitHub, calls APIs you pay for. Show a real query. \"the agent just looked.\" */}\n\n## Databases, browsers, GitHub, APIs\n\nOnce it is wired, \"the agent cannot know that\" becomes \"the agent just looked.\" Instead of assuming a number, it runs the query:\n\n```\nSELECT count(*) FROM users\nWHERE created_at > now() - interval '7 days';\n```\n\nInstead of describing a bug it drives a real browser and reads the console. Instead of narrating a change it opens the pull request, the change packaged up for review. Each connection turns a guess into a fact.\n\n{/* KEEP: custom tools = when no server exists, write one: a small named function with a TYPED input so the model calls it correctly every time. Show a @tool example. You give it a few exact levers, not everything. */}\n\n## Custom tools\n\nWhen no ready-made server exists, you write one, in whatever language your tool's SDK uses. A custom tool is a small named function with a typed input, so the model calls it the same way every time:\n\n```python\n@tool\ndef send_alert(message: str, level: Literal[\"info\", \"critical\"]) -> str:\n    \"\"\"Notify the operator. Use 'critical' only for outages.\"\"\"\n    post_to_channel(message, level)\n    return \"sent\"\n```\n\nYou are not teaching the agent everything. You are handing it a few exact levers that do the specific things your system needs.\n\n{/* KEEP: when a tool beats a prompt = if you explain the same procedure in prose more than twice, make it a tool. Prompts = judgment; tools = exact, repeatable actions. Move the mechanical into typed tools, leave the prompt for thinking. */}\n\n## When a tool beats a prompt\n\nThe rule of thumb: if you explain the same procedure in prose more than twice, it wants to be a tool. Prompts are for judgment; tools are for actions that must be exact and repeatable.\n\n\"Carefully format the currency like this, round like that\" is a tool waiting to be written. Move the mechanical into tools, and leave the prompt for thinking.\n\n{/* KEEP: prompt = have the agent wire up one MCP server for the reader's stack (or write one custom tool) so it can check reality. Ends with Do this now. */}\n\n## Wire up your first tool\n\nThis prompt connects your agent to something real:\n\n```\nAct as a senior engineer connecting my agent to my stack.\nPick the one connection that would help most right now (my\ndatabase, my repo, or my browser), set up its MCP server in\nmy tool's config, and show me one real check it can now run\ninstead of guessing.\n\nMy stack and what I want it to see:\n```\n\n**Do this now:** paste the prompt and wire up one connection, then ask your agent a question it can only answer by actually looking."
          },
          {
            "slug": "multiple-agents",
            "title": "When One Agent Isn't Enough",
            "label": "Multi-Agent",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/ai-os/multiple-agents",
            "content": "---\nshare: \"One agent doing everything is a solo founder doing every job: it works until it doesn't. The fix is not a bigger agent, it is more agents, each doing less, handing work to the next.\"\n---\n{/* KEEP: lead-in = one agent doing everything is a solo founder doing every job; works until it doesn't. The fix isn't a bigger agent, it's more agents each doing less. CODE-FORWARD. */}\n\nOne agent doing everything is a solo founder doing every job. It holds up until it does not. The fix is not a bigger agent, it is more agents, each doing less, each handing clean work to the next.\n\n{/* KEEP: signs one agent isn't enough = loses the thread on long tasks; plans+builds+reviews in one breath so the review is soft (same mind grading its own work); context fills; quality sags on anything with several moving parts. */}\n\n## Signs one agent isn't enough\n\nYou feel it before you can name it. The agent starts strong and loses the thread on a long task. It plans, builds, and reviews in one breath, and the review is soft because the same mind that wrote the code is grading it.\n\nIts context fills up, and quality sags on anything with more than a few moving parts. Those are the signals that the work has outgrown a single seat.\n\n{/* KEEP: the first and most powerful split is by PHASE: one plans, one builds, one reviews with fresh eyes. The reviewer catches what the builder can't see precisely because it didn't write it. Separation of roles = separation of blind spots. */}\n\n## Planner, builder, reviewer\n\nThe first and strongest split is by phase. One agent plans the work, another builds it, a third reviews it with fresh eyes.\n\nThis mirrors how real teams work, and for the same reason: the reviewer catches what the builder cannot see, precisely because it did not write the thing. Separation of roles is separation of blind spots.\n\n{/* KEEP: beyond phases, spin up specialists (security reviewer, test writer, researcher), each with its own skills + narrow standard of \"good.\" A specialist beats a generalist on its home turf because its whole config is bent toward one job. Each is a role file (ref configuring-agents). */}\n\n## Specialized agents\n\nBeyond the phases, you spin up specialists: a security reviewer, a test writer, a researcher. Each is a role file of its own, with its own skills and its own narrow standard of good.\n\nA specialist beats a generalist on its home turf, because its whole configuration is bent toward one kind of excellence. You assemble a team, not a hero.\n\n{/* KEEP: the team is only as good as its handoffs; one agent's output must become the next's input cleanly. File-based handoff: agent A writes a file with frontmatter (source, verdict); agent B reads it and stamps it (planned_in) so it isn't re-read. The FILE is the contract. Show the frontmatter. */}\n\n## Handoffs between them\n\nA team is only as good as its handoffs. One agent's output has to become the next one's input with nothing lost in the gap. The cleanest handoff is a file: agent A writes it, agent B reads it.\n\n```\n---\nsource: error-report\nverdict: needs-fix\nhandled_by: null\n---\nCheckout throws on empty cart. Repro + fix below.\n```\n\nThe builder writes that, the reviewer reads it and stamps `handled_by` so it is never picked up twice. The file is the contract between agents, so no context lives only in one agent's head.\n\nSomeone has to run the team, and it is simpler than it sounds: one lead agent spawns the others with a clear brief each, waits, and reads back their summaries to decide what happens next. The children do not talk to each other. Reads fan out freely; writes to the same file stay with one agent, so two never edit it at once and clobber each other.\n\n{/* KEEP: prompt = split the reader's one agent into a builder + a separate reviewer with a clean file handoff. Ends with Do this now. */}\n\n## Split your first team\n\nThis prompt turns your one agent into a small team:\n\n```\nAct as a senior engineer setting up a two-agent workflow.\nGive me a builder role and a separate reviewer role in my\ntool's format, and a simple file-based handoff: the builder\nwrites what it changed to a file, the reviewer reads that\nfile and reports issues before I commit. Keep both short.\n\nMy tool and project:\n```\n\n**Do this now:** paste the prompt, set up the builder and reviewer, and run one change through both so you see the reviewer catch what the builder missed."
          },
          {
            "slug": "scheduling-your-agents",
            "title": "Putting Agents on a Clock",
            "label": "Scheduling",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/ai-os/scheduling-your-agents",
            "content": "---\nshare: \"The best work an agent does is the work you never asked for, because it was already on the calendar. Scheduling is how your system runs while you sleep and you wake up to finished work.\"\n---\n{/* KEEP: lead-in = the best work an agent does is the work you never asked for because it was on the calendar; scheduling is how the system runs while you sleep. CODE-FORWARD, cron-simple. */}\n\nThe best work an agent does is the work you never asked for, because it was already on the calendar. Scheduling is how your system stops waiting for you and starts running on its own, so you wake up to work that is already done.\n\n{/* KEEP: until now every agent waited for you to start it; scheduling flips that: put an agent on a clock and it runs on its own, on time, whether you show up or not. The system stops being a tool you operate and becomes one that operates. */}\n\n## Agents that run without you\n\nUntil now, every agent waited for you to press go. Scheduling flips that. You put an agent on a clock and it runs on its own, on time, whether or not you show up.\n\nThat is the moment the system stops being a tool you operate and starts being one that operates, doing the rounds because the clock struck, not because you remembered.\n\n{/* KEEP: look at everything you do on a rhythm (weekly numbers, daily health check, monthly money review); each is a scheduled agent. Show a cron line (plain). Write the job once, set cadence, runs forever. The important-but-never-urgent work finally gets done because a clock doesn't procrastinate. Bold-first: cron. */}\n\n## Put the routine work on a clock\n\nLook at everything you do on a rhythm: the weekly numbers, the daily health check, the monthly money review. Every one is a scheduled agent waiting to exist.\n\nYou set its cadence with a [**cron**](https://crontab.guru) line, five fields that mean \"run at this time\":\n\n```\n# min hour day month weekday\n0 8 * * *      # every day at 08:00\n0 9 * * 1      # every Monday at 09:00\n```\n\nWrite the job once, give it a cadence, and it runs forever. The work that is important but never urgent, and so never gets done, finally does, because a clock does not procrastinate.\n\nThat format is cron, which is built into Mac and Linux. Windows has the same thing under a different name, Task Scheduler. You do not set either up by hand: you tell your agent the cadence and let it wire the right one for your machine.\n\n{/* KEEP: two ways to fire the same job: on a schedule (every morning) or on demand (one command, now). You want both. Nod that event-driven triggers come later. A job runner (Prefect-style) exists for scale, one line, swappable. */}\n\n## Schedule it, or trigger it on demand\n\nThe same job has two doors. On a schedule, it runs every morning at eight. On demand, you run one command and it goes now. You want both: the schedule for the rhythm, the manual run for the moment you need the report early.\n\nA plain cron runs this on your machine; a [job runner](https://prefect.io) handles it at scale when you have many. Same idea, bigger engine.\n\n{/* KEEP: a scheduled run without safety+observability rots silently. The three things that make an unattended run safe: it checks it's still allowed before acting (gate), it records what it did (ledger, built next chapters), and something alerts you if it STOPS firing (watchdog). The scary failure of a scheduler is silence, not a crash. Numbered flow = device variety in the back half. */}\n\n## Make an unattended run safe\n\nA job that runs while you sleep needs more than a clock, or it fails in the dark and you find out late. Three things make an unattended run trustworthy:\n\n1. **Gate:** before it acts, the agent confirms it is still allowed to (the guardrails of the next chapter). It fixes what is safe and escalates the rest, never spending or deleting on its own.\n2. **Record:** every run writes what it did to one log (you build this in the ledger chapter), so \"what ran last night\" has one honest answer.\n3. **Watchdog:** something alerts you when a run stops firing. A scheduler does not fail loudly; it goes quiet, so you alert on the missing run, not just on errors.\n\n{/* KEEP: the payoff = open your laptop and the reports are written, checks run, problems flagged or fixed; you review work that already happened. The system ran a full shift without you. */}\n\n## Wake up to finished work\n\nThis is the payoff, and it changes how the whole thing feels. You open your laptop and the reports are already written, the checks already run, the problems already flagged or fixed.\n\nYou are not starting the day's work. You are reviewing work that already happened. The system ran a full shift while you slept.\n\n{/* KEEP: prompt = take one routine task the reader does on a rhythm and turn it into a scheduled agent with a cron + a job definition. Ends with Do this now. */}\n\n## Put one job on a clock\n\nThis prompt turns a routine chore into a scheduled agent:\n\n```\nAct as a senior engineer automating my routine work. Take\nthe one task I describe below, write it as a small job my\nagent can run on its own, and schedule it at the right\ncadence using whatever my operating system provides (cron on\nMac or Linux, Task Scheduler on Windows). Show me how to run\nit once by hand to test it first.\n\nMy operating system and the routine task (and how often):\n```\n\n**Do this now:** paste the prompt, pick one thing you do on a rhythm, and let your agent turn it into a job on a clock."
          },
          {
            "slug": "autonomy-guardrails",
            "title": "What Runs Alone, What Waits for You",
            "label": "Autonomy",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/ai-os/autonomy-guardrails",
            "content": "---\nshare: \"Autonomy without guardrails is a loaded gun on a timer. Sort every action into safe-to-run-alone and must-wait-for-you, so the tireless work happens and only the risky calls reach you.\"\n---\n{/* KEEP: lead-in = this is the safety layer that keeps autonomy from hurting you. Autonomy without guardrails = a loaded gun on a timer. MUST come right after Scheduling. CODE-FORWARD. */}\n\nYou just put agents on a clock. That is power, and power without a brake is dangerous: an agent that can act on its own, on a schedule, can also break things on its own. This chapter is the brake, the line between what runs alone and what waits for you.\n\n{/* KEEP: not every action is equal; reading a dashboard and deleting an account are not the same risk. Sort every action into two buckets: safe to run alone (reversible, low blast radius) vs must wait for a human yes (money, real user data, security, removing a capability). The sort is the whole game. */}\n\n## Not every action is equal\n\nReading a dashboard and deleting a customer's account are not the same risk, so they must not have the same freedom. You sort every action an agent can take into two buckets.\n\nReversible, low-risk work runs on its own. Anything that touches money, real user data, security, or removes a capability stops and asks. That sort is the whole game.\n\n{/* KEEP: give agents a standing rule: fix what you're allowed to fix; for everything else, don't act, drop a card. Safe repair -> do it and log it. Risky (raise the bill, swap a vendor, change a price) -> write a short decision card, leave it in the queue. The agent never grows the stakes on its own. */}\n\n## Fix what's safe, escalate what's not\n\nGive every autonomous agent one standing rule: fix what you are allowed to fix, and for everything else, do not act, leave a card.\n\nWhen a scheduled agent finds a problem it can safely repair, it repairs it and logs it. When it finds something only you should decide, raising the bill, swapping a vendor, changing a price, it writes a short **decision card** and stops. The agent never raises the stakes on its own.\n\n{/* KEEP: the decision queue = all escalations land in ONE place, one card each (one question, one recommendation); you clear it on your schedule, approving or rejecting. This is what makes autonomy safe to live with: the system does the tireless work and hands you only the small set of real judgment calls. Show a decision card. */}\n\n## The decision queue\n\nEvery escalation lands in one place: a queue of decisions waiting on you. Each is one card, one question, one recommendation.\n\n```\n# decision: raise the DB plan?\nWhy: we hit 90% of storage twice this week.\nRecommend: upgrade one tier (+$25/mo).\nOptions: approve / hold / do something else\n```\n\nYou clear the queue on your own schedule, approving or rejecting each. An approved card becomes a line in the decision log back in your cockpit, so the call and its reason are recorded, not lost. This is what makes autonomy safe to live with: the system does the tireless work and hands you only the handful of calls that would hurt to get wrong.\n\n{/* KEEP: the hard lines can't live in your head or a mood; they live in rules files, always on, phrased as absolutes (never change billing without a yes, never delete without confirmation, never message a customer without approval). Each rule names a specific way things go wrong. Short, brutal, permanent, fires every turn. */}\n\n## Write the hard lines down, once\n\nThe guardrails cannot live in your memory. They live in a rules file, always loaded, phrased as absolutes:\n\n```\n# rules/guardrails.md\n- Never change billing or pricing without an explicit yes.\n- Never delete user data without confirmation.\n- Never send anything to a customer without approval.\n```\n\nEvery rule earns its place by naming a specific way things go wrong. The list is short, blunt, and permanent, and it fires on every turn whether the agent thinks to consider it or not.\n\nA rule the agent reads is a rule it can talk itself out of over a long, tired session. For the lines that must never break, add a second layer: a **hook**, a small script your tool runs automatically that mechanically blocks the action, no judgment involved. The rule tells the agent what not to do; the hook makes it impossible. Anything that spends money, deletes real data, or ships to production belongs behind a hook, not just a sentence.\n\n{/* KEEP: prompt = have the agent split its own actions into safe/escalate and write the guardrail rules file for the reader's system. Ends with Do this now. */}\n\n## Draw your own lines\n\nThis prompt sets your guardrails before you let anything run alone:\n\n```\nAct as a senior engineer setting safety guardrails for my\nautonomous agents. From what my system can touch, list which\nactions are safe to run alone (reversible, low risk) and\nwhich must wait for my approval (money, user data, security,\ndeletions). Then write a short always-on rules file that\nencodes the must-wait lines as absolutes.\n\nWhat my agents can do and touch:\n```\n\n**Do this now:** paste the prompt, get your safe/escalate split and a guardrails rules file, and add it to your agents' always-on rules before any of them run on a schedule."
          },
          {
            "slug": "reports-and-commands",
            "title": "Commands and What Comes Back",
            "label": "Reporting",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/ai-os/reports-and-commands",
            "content": "---\nshare: \"A system you cannot see is one you cannot steer. Reporting is the two-way pipe: you send one command down, the work sends truth back up, and you sit at the top of the loop, not inside it.\"\n---\n{/* KEEP: lead-in = a system you can't see is one you can't steer. Reporting = the two-way pipe: commands down, reports up. You sit at the top of the loop, not inside it. CODE-FORWARD. */}\n\nA system you cannot see is a system you cannot steer. Reporting is the two-way pipe that lets you run the whole thing from one seat: you send commands down, the work sends truth back up, and you stay at the top of the loop instead of buried inside it.\n\n{/* KEEP: the shape of control: direction flows DOWN from you as commands, reality flows UP from agents as reports. You point the system at what matters and read back what it found. Down goes intent, up comes evidence, you sit where they meet. */}\n\n## You command down, they report up\n\nThe shape of control is simple. Direction flows down from you as commands. Reality flows up from the agents as reports.\n\nYou do not do the tasks. You point the system at what matters, and you read back what it found. Down goes intent, up comes evidence, and you sit where the two meet.\n\n{/* KEEP: commands are your interface; don't operate by remembering ten folders and twenty scripts. A small set of named commands: one for the whole picture, one per area to go deeper. The command is one word; behind it is all the machinery. A good command set is the entire UI of your system. Show the command set. */}\n\n## Commands are your interface\n\nYou should not run the system by remembering ten folders and twenty scripts. You run it through a small set of named commands, each a single word that hides a mountain of machinery:\n\n```\n/status        # the whole picture, one screen\n/status growth # traffic, users, money\n/status tech   # errors, cost, agents\n```\n\nOne to see everything, one per area to go deeper. A good command set is the entire user interface of your operation.\n\nA command is a real file, not magic: in Claude Code each one is a markdown file in `.claude/commands/` (`status.md` becomes `/status`), holding the instructions the command runs. Your tool has the same idea under its own name. You write the workflow once; the slash name is the shortcut.\n\n{/* KEEP: reports are what comes back; every agent that works leaves a report (what it checked, found, did, what needs you), in a KNOWN place and KNOWN shape so you scan many fast. The report compresses a night of work into five minutes of reading, so you spend attention only on deciding. Show report frontmatter. */}\n\n## Reports are what comes back\n\nEvery agent that does work leaves a report: what it checked, what it found, what it did, and what needs you. They land in a known place, in a known shape, so you can scan many of them fast:\n\n```\n---\narea: money\nverdict: needs-you\n---\nRevenue up 4%. One failed payout, decision card filed.\n```\n\nA keyed shape like that is what turns a night of autonomous work into five minutes of reading. It compresses the doing so you spend your attention only on the deciding. Reports land in their own `reports/` folder, separate from the department status files: a status file is a department's current truth, a report is one run's findings for you.\n\n{/* KEEP: keep the loop tight = the danger is a leaky loop (reports nobody reads, commands that no longer match the folders, a gap between what the system did and what you think it did). Fight it: one command surface, one report format, one place the truth lives. The tighter the loop, the more you can trust it, and trust is what lets you let go. */}\n\n## Keep the loop tight\n\nThe danger is a loop that leaks: reports nobody reads, commands that no longer match the folders, a gap between what the system did and what you think it did.\n\nYou fight that constantly with three disciplines: one command surface, one report format, one place the truth lives. The tighter the loop, the more you can trust it, and trust is the only thing that lets you actually let go.\n\n{/* KEEP: prompt = have the agent set up the reader's command surface (one status command + a report format) over their operating base. Ends with Do this now. */}\n\n## Build your command surface\n\nThis prompt gives you one seat to run everything from:\n\n```\nAct as a senior engineer building my command surface. Over\nmy operating base, create one command that reads every\ndepartment's status file and its latest reports into a\nsingle briefing, showing what needs me. Define one short\nreport format (keyed frontmatter) that every agent writes.\n\nMy operating base and departments:\n```\n\n**Do this now:** paste the prompt, set up your one status command and report format, then run the command once and read your whole operation on a single screen."
          },
          {
            "slug": "event-ledger",
            "title": "One Log of Everything That Happened",
            "label": "Ledger",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/ai-os/event-ledger",
            "content": "---\nshare: \"Reports tell you what happened this morning. A ledger tells you everything that ever happened, in order. The one place to answer 'what led to this' when something goes wrong.\"\n---\n{/* KEEP: lead-in = reports = this morning; a ledger = everything that ever happened, in order. LIGHTER chapter (idea + when you need it), flag that a beginner may not need it yet. One small artifact. */}\n\nReports tell you what an agent found this morning. A ledger tells you everything that has ever happened, in order. You will not need it on day one, but the first time you ask \"what led to this?\" and cannot answer, this is the missing piece.\n\n{/* KEEP: under the folders and agents, one append-only log of events (deploy happened, signup came, alert fired, job finished). Each meaningful thing writes one line. Not a report you read top to bottom, the raw record everything pulses through. Show a small event log. */}\n\n## Events are the nervous system\n\nUnderneath the folders and the agents, you keep a **ledger**: one running log of **events**. A deploy happened. A signup came in. An alert fired. A job finished. Every meaningful thing writes one line:\n\n```\n2026-07-10T08:00Z  job.finished    growth-daily ok\n2026-07-10T08:14Z  signup          user=4821\n2026-07-10T09:02Z  alert.fired     errors spiking\n```\n\nIt is not a report you read top to bottom. It is the raw record the whole system pulses through, the thing everything else can look back at.\n\n{/* KEEP: one rule makes it trustworthy: append only, never edit. A line once written stays; you never rewrite history. That's what lets you reconstruct exactly what happened weeks later, the truth, not a tidied summary. */}\n\n## Append only, never edit\n\nThe ledger has one rule that makes it trustworthy: you only ever add to it. You never rewrite a line.\n\nThat is what lets you reconstruct exactly what happened, and in what order, weeks later when something broke and you need the truth, not a summary someone tidied up. Its value is that nobody got to clean it.\n\n{/* KEEP: the power shows when local AND cloud write to the SAME ledger: the agent on your laptop and the service in production log to one stream, giving one timeline of the whole system. Ask \"what led to this\", one place to look, complete answer. */}\n\n## One place, both worlds\n\nThe real power shows up when your local work and your live service write to the same ledger. The way it works is one small rule: everything that logs an event calls the same single writer, the agent on your laptop and the app in production both append through one door, so there is one stream and not two.\n\nNow you have a single timeline of the whole system, machine and human, code and business, in one order. This is the third and last record surface, and each has one job: a department's status file is its current truth, a report is one run's findings for you, the ledger is the raw timeline for looking back. When you ask \"what led to this,\" the ledger is the one place to look.\n\n{/* KEEP: a durable event stream isn't just for looking back, it's the surface agents can WATCH and react to; once you have one honest log, you can build agents that fire the instant an event lands. This sets up Triggers. Flag WHEN to add a ledger. */}\n\n## The ledger makes reflexes possible\n\nA durable stream of events is not only for looking back. It is the surface an agent can watch, so it can react the instant a certain event lands. That is the next chapter.\n\n> **Hint:** you do not need a ledger while it is just you and a few daily agents. Add one when you cannot answer \"what led to this,\" or when you want agents that react to events. Your plain log is the simple version; at scale the industry standard for this is [OpenTelemetry](https://opentelemetry.io/docs/specs/semconv/gen-ai/), which records the same kind of timeline in a format built for it.\n\n{/* KEEP: prompt = start a simple append-only event log the reader's agents write one line to. Ends with Do this now. */}\n\n## Start your ledger\n\nThis prompt gives your system a memory of its own history:\n\n```\nAct as a senior engineer adding an event log to my system.\nCreate one append-only file my agents write a single line\nto whenever something meaningful happens (a job finished, a\nsignup, an alert). Give each line a timestamp, an event\nname, and a short detail. Never edit past lines.\n\nMy system and the events worth logging:\n```\n\n**Do this now:** paste the prompt, start the log, and have one of your scheduled agents append a line every time it runs."
          },
          {
            "slug": "triggers",
            "title": "Agents That React, Not Just Wait",
            "label": "Triggers",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/ai-os/triggers",
            "content": "---\nshare: \"Scheduling put agents on a clock, but some work can't wait for the clock. A trigger is a reflex: an agent that fires the instant something happens, so the gap between it broke and we responded is near zero.\"\n---\n{/* KEEP: lead-in = scheduling put agents on a clock, but some work can't wait for the clock, it must happen the instant something occurs, that's the reflex. LIGHTER chapter, pairs with the ledger. */}\n\nScheduling put your agents on a clock. But some work cannot wait for the clock: it has to happen the instant something occurs. That is the other half of autonomy, the reflex, and it is what this short chapter adds.\n\n{/* KEEP: a scheduled agent asks \"is it time yet\"; a triggered agent asks \"did the thing happen\". One is a heartbeat (steady, periodic), the other a reflex (dormant until an event, then instant). A serious system has both. */}\n\n## Scheduled is proactive, triggered is immediate\n\nA scheduled agent asks, \"is it time yet?\" A **triggered** agent asks, \"did the thing happen?\"\n\nThe first is a heartbeat, steady and periodic. The second is a **reflex**, dormant until an event pokes it, then instant. A serious system has both: the heartbeat does the rounds, the reflex catches the fire the moment it starts.\n\n{/* KEEP: some problems can't wait for the next sweep: a payment fails, a key expires, an error spikes. If your only mechanism is a schedule, damage runs until the next tick. Reflexes are for events where the gap between \"it happened\" and \"we responded\" must be near zero. Smoke detector, not a morning check. */}\n\n## Some problems can't wait for the next sweep\n\nA payment fails. A key expires. An error spikes. If your only mechanism is a schedule, the damage runs until the next tick fires.\n\nReflexes exist for exactly the events where the gap between \"it happened\" and \"we responded\" has to be near zero. You do not schedule a smoke detector to check for fire each morning; you wire it to react the instant there is smoke.\n\nHere is the whole loop on one event. An error lands in the ledger. The reflex wakes, pulls the real context, the stack trace, the recent changes, the live state, and works out what broke. Then it splits on the guardrails you already set: if the fix is safe and reversible it makes it, proves it with a test, and ships it through review; if it would cost money or touch user data, it does not act, it files a decision card and stops. Investigating is always safe, so that part is fully automatic; only the risky call waits for you.\n\n{/* KEEP: a reflex = an agent watching the event stream for a specific line; when that event lands, it fires, does its one job, goes back to sleep. This is why the ledger comes first: no honest event stream = nothing to react to. Show a tiny trigger rule (on event -> run agent). */}\n\n## Triggers listen to the ledger\n\nA reflex is an agent watching the event stream for one specific line. Something has to do the watching, and the simplest version is a small watcher on a tight loop: it reads new lines in the ledger every few seconds, and when a line matches, it runs the right agent. Bigger setups let the alerting tool itself call a web address the moment it fires, but the idea is the same, a rule that maps an event to an agent:\n\n```\non event  alert.fired    -> run  incident-responder\non event  payment.failed -> run  billing-retry\n```\n\nThis is why the ledger comes first: without one honest stream of events, there is nothing to watch. With it, any event can become a trigger.\n\n{/* KEEP: heartbeat + reflex = complete coverage of time. Scheduled agents handle the rhythm (routine on a cadence); triggered agents handle the surprises (events that arrive on their own). Between them nothing falls through. Flag lighter: add reflexes when you have events worth reacting to. */}\n\n## Together they cover the whole clock\n\nHeartbeat plus reflex is complete coverage of time. The scheduled agents handle the rhythm of the work, the routine that happens on a cadence. The triggered agents handle the surprises, the events that arrive on their own and demand a response now.\n\nBetween the two, nothing falls through: if it happens on a clock, the heartbeat has it; if it just happens, a reflex catches it.\n\n> **Hint:** reach for reflexes once you have a ledger and a few events that genuinely cannot wait for the next scheduled run.\n\n{/* KEEP: prompt = wire one reflex: watch for a specific event in the ledger and run an agent when it lands. Ends with Do this now. */}\n\n## Wire your first reflex\n\nThis prompt gives your system its first reflex:\n\n```\nAct as a senior engineer adding an event-driven trigger to\nmy system. Pick the one event that most needs an instant\nresponse, watch my event log for it, and run the right agent\nthe moment it lands. Use an approach that works on my\noperating system. Keep the agent's job small and safe,\ninside the guardrails I already set.\n\nMy operating system, event log, and the event that can't wait:\n```\n\n**Do this now:** paste the prompt and wire one reflex to the single event you would hate to catch a day late."
          }
        ]
      },
      {
        "id": "architect",
        "title": "Lay out a modular codebase for your AI",
        "chapters": [
          {
            "slug": "modular-foundation",
            "title": "A Foundation That Bends",
            "label": "Modularity",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/architect/modular-foundation",
            "content": null
          },
          {
            "slug": "folder-structure",
            "title": "Where Everything Lives",
            "label": "Structure",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/architect/folder-structure",
            "content": null
          },
          {
            "slug": "coupling-and-cohesion",
            "title": "Keeping Pieces Independent",
            "label": "Coupling",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/architect/coupling-and-cohesion",
            "content": null
          },
          {
            "slug": "boundaries-and-layers",
            "title": "Drawing the Boundaries",
            "label": "Layers",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/architect/boundaries-and-layers",
            "content": null
          },
          {
            "slug": "api-design",
            "title": "Contracts That Last",
            "label": "API Design",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/architect/api-design",
            "content": null
          },
          {
            "slug": "conventions-and-naming",
            "title": "Naming Things Consistently",
            "label": "Conventions",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/architect/conventions-and-naming",
            "content": null
          },
          {
            "slug": "architecture-handoff",
            "title": "Teaching Your AI the Architecture",
            "label": "Handoff",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/architect/architecture-handoff",
            "content": null
          },
          {
            "slug": "documentation",
            "title": "Writing for Humans and AI",
            "label": "Docs",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/architect/documentation",
            "content": null
          }
        ]
      },
      {
        "id": "build",
        "title": "Implement the application in working slices",
        "chapters": [
          {
            "slug": "scaffolding",
            "title": "Blank Screen to Running App",
            "label": "Scaffolding",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/build/scaffolding",
            "content": null
          },
          {
            "slug": "directing-your-agent",
            "title": "Steering Your Agent",
            "label": "Direction",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/build/directing-your-agent",
            "content": null
          },
          {
            "slug": "prompting",
            "title": "Instructing the Agent Well",
            "label": "Prompting",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/build/prompting",
            "content": null
          },
          {
            "slug": "context-engineering",
            "title": "Keeping the Agent Smart",
            "label": "Context",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/build/context-engineering",
            "content": null
          },
          {
            "slug": "working-in-small-steps",
            "title": "Working in Small Steps",
            "label": "Increments",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/build/working-in-small-steps",
            "content": null
          },
          {
            "slug": "guardrails",
            "title": "Catching Bugs Before They Happen",
            "label": "Guardrails",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/build/guardrails",
            "content": null
          },
          {
            "slug": "reviewing-the-agents-code",
            "title": "Checking the Agent's Work",
            "label": "Code Review",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/build/reviewing-the-agents-code",
            "content": null
          }
        ]
      },
      {
        "id": "debug",
        "title": "Diagnose and fix what the agent breaks",
        "chapters": [
          {
            "slug": "stack-traces",
            "title": "Reading What Broke",
            "label": "Stack Traces",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/debug/stack-traces",
            "content": null
          },
          {
            "slug": "agent-loops",
            "title": "When Your Agent Goes in Circles",
            "label": "Loops",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/debug/agent-loops",
            "content": null
          },
          {
            "slug": "bisecting",
            "title": "Finding the Change That Broke It",
            "label": "Bisecting",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/debug/bisecting",
            "content": null
          },
          {
            "slug": "verifying-fixes",
            "title": "Is It Actually Fixed?",
            "label": "Verification",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/debug/verifying-fixes",
            "content": null
          },
          {
            "slug": "rollback",
            "title": "Reverting Safely",
            "label": "Rollback",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/debug/rollback",
            "content": null
          },
          {
            "slug": "getting-unstuck",
            "title": "Getting Unstuck",
            "label": "Escalation",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/debug/getting-unstuck",
            "content": null
          }
        ]
      },
      {
        "id": "harden",
        "title": "Make it secure, tested, and reliable",
        "chapters": [
          {
            "slug": "designing-the-interface",
            "title": "Designing How It Looks and Feels",
            "label": "Interface",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/harden/designing-the-interface",
            "content": null
          },
          {
            "slug": "data-accounts-and-payments",
            "title": "Data, Users, and Payments",
            "label": "Accounts",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/harden/data-accounts-and-payments",
            "content": null
          },
          {
            "slug": "database-migrations",
            "title": "Changing the Database Safely",
            "label": "Migrations",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/harden/database-migrations",
            "content": null
          },
          {
            "slug": "validating-input",
            "title": "Trusting No Input",
            "label": "Validation",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/harden/validating-input",
            "content": null
          },
          {
            "slug": "making-it-reliable",
            "title": "Handling Failure Gracefully",
            "label": "Reliability",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/harden/making-it-reliable",
            "content": null
          },
          {
            "slug": "testing-and-qa",
            "title": "QA Before Users Find It",
            "label": "Testing",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/harden/testing-and-qa",
            "content": null
          },
          {
            "slug": "refactoring",
            "title": "Paying Down AI Debt",
            "label": "Refactoring",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/harden/refactoring",
            "content": null
          },
          {
            "slug": "security",
            "title": "Locking It Down",
            "label": "Security",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/harden/security",
            "content": null
          },
          {
            "slug": "accessibility-and-performance",
            "title": "Speed and Accessibility",
            "label": "Performance",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/harden/accessibility-and-performance",
            "content": null
          }
        ]
      },
      {
        "id": "ship",
        "title": "Deploy to production on real infrastructure",
        "chapters": [
          {
            "slug": "deploying-to-production",
            "title": "Going to Production",
            "label": "Deployment",
            "status": "published",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/ship/deploying-to-production",
            "content": "---\nshare: \"Your app runs on your laptop and nobody else can reach it. Going to production means putting it on real infrastructure the world can use, rebuildable from files, not clicked together by hand.\"\n---\n{/* KEEP: lead-in = your app works on your machine, no one else can open it. Production = the leap to a real server the world reaches, carried by ONE mindset: the whole setup is rebuildable from files, not clicked by hand. This chapter frames the whole Ship part. */}\n\nYour app works on your machine, and nobody else can open it. Production is the leap to a real server the world can reach. This chapter gets you there, and hands you the one mindset that makes every later step in this part sane: the whole setup is rebuildable from files, never clicked together by hand.\n\n{/* KEEP: concept = production is not a place you configure by hand once; anything set by clicking a dashboard is lost the day the server dies. Real production is described in files you re-run to recreate the whole thing. Bold-first: production. */}\n\n## Production is rebuildable, not clicked\n\n**Production** is not a machine you configure by hand and hope never dies. Anything you set by clicking around in a dashboard is gone the day that server does, and you are rebuilding it from memory.\n\nReal production is described in files. You run those files and the whole setup comes back, identical, on a fresh machine. That single idea is what the rest of this part builds, so treat every by-hand click as a note you still have to turn into a file.\n\n{/* KEEP: pick where it runs; honest default = cheap own-the-metal, not the big-cloud maze. A small box on a provider like Hetzner costs a fraction of the hyperscaler equivalent and you don't pay a tax for 100 services you'll never use. Rule of thumb: avoid the AWS maze unless you have a reason; if you must, raw EC2. Link Hetzner. */}\n\n## Pick a host you can afford to keep\n\nThe honest default is cheap, own-the-metal hosting, not the big-cloud maze. A small server on a provider like [Hetzner](https://www.hetzner.com) costs a fraction of the same box on a hyperscaler, and you are not paying a tax for a hundred managed services you will never touch.\n\n> **Rule of thumb:** skip the AWS managed maze unless you have a specific reason to be in it. If you must be on AWS, a plain server (an EC2 box) beats wiring ten services together to run one app.\n\n{/* KEEP: do it by hand ONCE so you see every piece (a server, a domain, the app running, a way in); automating something you've never done by hand hides the parts that break. Then never again: capture each step as files, a deploy becomes a command not an afternoon. Prompt has agent draft the deploy plan for their host. */}\n\n## Deploy by hand once, then never again\n\nThe first time, do it by hand. Stand up a server, point a domain at it, get the app running, and open it from another device. Doing it once shows you every moving part, and automating a thing you have never done by hand only hides where it breaks.\n\nThen you never do it by hand again. Every step you just took becomes a file in the chapters that follow, and from then on a deploy is one command, not a lost afternoon.\n\nThis prompt turns your first deploy into a written plan:\n\n```\nAct as a senior engineer planning my first production\ndeploy. For my stack and chosen host, lay out the smallest\nreal path to live: the server, the domain and TLS, how the\napp runs, and how I reach it. Keep it manual for now, but\nnote which step becomes a file I automate later.\n\nMy stack and host:\n```\n\n**Do this now:** paste the prompt, get your manual deploy plan, and stand the app up on a real host once, by hand."
          },
          {
            "slug": "dev-staging-production",
            "title": "Dev, Staging, Production",
            "label": "Environments",
            "status": "published",
            "access": "paid",
            "url": "https://zalt.me/guides/vibe-coding/ship/dev-staging-production",
            "content": null
          },
          {
            "slug": "infrastructure-as-code",
            "title": "Infrastructure as Code",
            "label": "IaC",
            "status": "published",
            "access": "paid",
            "url": "https://zalt.me/guides/vibe-coding/ship/infrastructure-as-code",
            "content": null
          },
          {
            "slug": "containers-and-kubernetes",
            "title": "Package and Run Your App",
            "label": "Containers",
            "status": "published",
            "access": "paid",
            "url": "https://zalt.me/guides/vibe-coding/ship/containers-and-kubernetes",
            "content": null
          },
          {
            "slug": "secrets-in-production",
            "title": "Keys and Passwords in Production",
            "label": "Secrets",
            "status": "published",
            "access": "paid",
            "url": "https://zalt.me/guides/vibe-coding/ship/secrets-in-production",
            "content": null
          },
          {
            "slug": "scripts-for-every-operation",
            "title": "One Command per Operation",
            "label": "Scripts",
            "status": "published",
            "access": "paid",
            "url": "https://zalt.me/guides/vibe-coding/ship/scripts-for-every-operation",
            "content": null
          },
          {
            "slug": "automating-your-deployment",
            "title": "Automating the Deploy",
            "label": "CI/CD",
            "status": "published",
            "access": "paid",
            "url": "https://zalt.me/guides/vibe-coding/ship/automating-your-deployment",
            "content": null
          },
          {
            "slug": "safe-releases-and-rollbacks",
            "title": "Safe Rollouts and Rollbacks",
            "label": "Releases",
            "status": "published",
            "access": "paid",
            "url": "https://zalt.me/guides/vibe-coding/ship/safe-releases-and-rollbacks",
            "content": null
          }
        ]
      },
      {
        "id": "operate",
        "title": "Run and maintain it in production",
        "chapters": [
          {
            "slug": "logging",
            "title": "Leaving a Trail",
            "label": "Logging",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/operate/logging",
            "content": null
          },
          {
            "slug": "observability",
            "title": "Seeing Inside Your App",
            "label": "Observability",
            "status": "draft",
            "access": "paid",
            "url": "https://zalt.me/guides/vibe-coding/operate/observability",
            "content": null
          },
          {
            "slug": "monitoring-and-alerts",
            "title": "Monitoring and Getting Paged",
            "label": "Alerting",
            "status": "draft",
            "access": "paid",
            "url": "https://zalt.me/guides/vibe-coding/operate/monitoring-and-alerts",
            "content": null
          },
          {
            "slug": "backups-and-disaster-recovery",
            "title": "Disaster Recovery",
            "label": "Backups",
            "status": "draft",
            "access": "paid",
            "url": "https://zalt.me/guides/vibe-coding/operate/backups-and-disaster-recovery",
            "content": null
          },
          {
            "slug": "maintenance-and-incidents",
            "title": "Maintenance When Things Break",
            "label": "Incidents",
            "status": "draft",
            "access": "paid",
            "url": "https://zalt.me/guides/vibe-coding/operate/maintenance-and-incidents",
            "content": null
          },
          {
            "slug": "watching-the-bill",
            "title": "Watching the Bill",
            "label": "Cost",
            "status": "draft",
            "access": "paid",
            "url": "https://zalt.me/guides/vibe-coding/operate/watching-the-bill",
            "content": null
          },
          {
            "slug": "automation",
            "title": "Letting the System Run Itself",
            "label": "Automation",
            "status": "draft",
            "access": "paid",
            "url": "https://zalt.me/guides/vibe-coding/operate/automation",
            "content": null
          }
        ]
      },
      {
        "id": "scale",
        "title": "Grow it to handle real traffic and data",
        "chapters": [
          {
            "slug": "bottlenecks",
            "title": "Finding the Limits",
            "label": "Bottlenecks",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/scale/bottlenecks",
            "content": null
          },
          {
            "slug": "caching-and-the-database",
            "title": "Easing the Database",
            "label": "Caching",
            "status": "draft",
            "access": "paid",
            "url": "https://zalt.me/guides/vibe-coding/scale/caching-and-the-database",
            "content": null
          },
          {
            "slug": "scaling-out",
            "title": "Adding Capacity",
            "label": "Horizontal Scaling",
            "status": "draft",
            "access": "paid",
            "url": "https://zalt.me/guides/vibe-coding/scale/scaling-out",
            "content": null
          },
          {
            "slug": "capacity-planning",
            "title": "Staying Ahead of Growth",
            "label": "Capacity Planning",
            "status": "draft",
            "access": "paid",
            "url": "https://zalt.me/guides/vibe-coding/scale/capacity-planning",
            "content": null
          },
          {
            "slug": "the-improvement-loop",
            "title": "The Improvement Loop",
            "label": "Optimization",
            "status": "draft",
            "access": "paid",
            "url": "https://zalt.me/guides/vibe-coding/scale/the-improvement-loop",
            "content": null
          },
          {
            "slug": "when-to-call-a-pro",
            "title": "When to Call a Pro",
            "label": "Expertise",
            "status": "draft",
            "access": "free",
            "url": "https://zalt.me/guides/vibe-coding/scale/when-to-call-a-pro",
            "content": null
          }
        ]
      }
    ]
  },
  {
    "id": "building-ai-agents",
    "title": "Designing Reliable\nAgentic AI Systems",
    "subtitle": "Architecting, orchestrating, and shipping autonomous agents that do real work, not demos.",
    "tagline": "Build scalable AI agents from scratch",
    "description": "Architecting, orchestrating, and shipping autonomous agents that do real work, not demos.",
    "author": "Mahmoud Zalt",
    "authorRole": "Principal AI Architect",
    "status": "coming-soon",
    "url": null,
    "coverImage": "/images-optimized/blog/auto/building-ai-agents-cover-medium.webp",
    "edition": "2027 Edition",
    "version": "v0.0",
    "parts": []
  }
]
