Stop prompting. Start specifying. Vibe turns AI code changes into reviewable, verifiable engineering — with hard file boundaries and mechanical acceptance checks.
change "add product search" { goal "Search products by title on the home page" scope { allow "src/**" forbid "src/payments/**" // never touched } requirements { "Search input at the top of the product list" "Search term reflected in the URL as ?q=" } acceptance { "typing a keyword narrows the list" run "npm test" } rollback revert }
Infrastructure became reliable when we stopped clicking buttons and started writing files. AI coding is at the same turning point.
Dockerfiledescribes how a container is built — reproducibly.
Makefiledescribes how tasks are executed — repeatably.
main.tfdescribes how infrastructure is provisioned — declaratively.
*.vibedescribes how AI modifies your code — within boundaries, with proof.
As more code is written and maintained by AI, the scarce skill is no longer writing code. It is specifying changes precisely enough that an AI can execute them and a machine can verify them. Vibe is the language for that skill.
Vibefiles live in .vibe/changes/ and go through pull-request review like any other source file.
Boundaries are enforced against the actual git diff. Acceptance commands must exit 0. CI-gateable.
The history of your Vibefiles is a machine-readable intent history: who changed what, within which limits, proven how.
Any AI coding CLI works as the executor — Cursor, Claude Code, aider, or your own script. The contract stays the same.
Natural language stays the fast input. The Vibefile is the engineering layer beneath it — compiled deterministically, enforced mechanically.
The compiler and verifier never call a model. Same input, same output, every single time.
File boundaries are checked after execution against the actual diff — never assumed from the agent's self-report.
vibe run — the whole loop.$ vibe run .vibe/changes/add-search.vibe === Attempt 1/2 === > executor edits the code... Verify "add product search": PASSED Scope check: OK PASS (exit 0) npm test RUN PASSED after 1 attempt(s). Review the diff and commit.
$ vibe run .vibe/changes/add-search.vibe === Attempt 2/2 === Verify "add product search": FAILED Scope violations (1): src/payments/charge.ts -> matches forbid "src/payments/**" RUN FAILED after 2 attempt(s). Rollback strategy is `revert`: restoring tracked files...
On failure, the verify report is fed back to the agent for a retry. If every
attempt fails, rollback revert restores the tree.
The AI's claims don't count — the git diff does.
One declaration, six blocks, about a dozen keywords. If a change has no scope, no requirements, or no acceptance — it does not compile. An ambiguous plan is a rejected plan.
goalOne sentence: what should be true after this change. It anchors everything else — the agent reads it first, your reviewer reads it first.
change "dark mode toggle" { goal "Users can switch the app to dark mode" /* ... */ }
scopeThe hard boundary. allow patterns say where the AI may write; forbid patterns always win, even when an allow also matches. Globs: ** crosses directories, * stays inside one.
scope { allow "src/ui/**" allow "src/theme.ts" forbid "src/auth/**" // forbid always wins forbid "prisma/**" // no schema changes }
requirementsConcrete instructions, one per line. A bare string means add this behavior; prefix with remove or modify when intent differs. Write them like you'd brief a careful contractor.
requirements { "Toggle button in the settings page header" "Preference persisted to localStorage" remove "the old high-contrast checkbox" }
acceptanceHow success is proven. A bare string is a behavioral check; run lines are commands that must exit 0 — typecheckers, tests, builds. These run mechanically after every attempt.
acceptance { "clicking the toggle flips the theme instantly" "the theme survives a page reload" run "npx tsc --noEmit" run "npm test" }
constraints & style (optional)Guard rails the agent must respect: dependency policy, API compatibility, design conventions. Conveyed verbatim in the agent's contract.
constraints { "no new npm dependency" "keep the public API unchanged" } style { "follow the existing component patterns" }
rollback (optional)revert restores tracked files automatically when all attempts fail. manual leaves the changes in place for inspection. Default is manual.
rollback revert // or: rollback manual
# 1. install (from a clone; npm package coming) $ git clone https://github.com/your-org/vibe-lang && cd vibe-lang $ npm install && npm run build && npm link # 2. scaffold .vibe/ in the repository you maintain $ cd ~/my-project $ vibe init # 3. point it at your AI CLI and run a change $ vibe run .vibe/changes/example.vibe
Configure any agent as the executor in .vibe/config.json —
placeholders {promptFile}, {prompt},
{repo}. No executor configured? vibe run
prints the contract for you to paste into any AI tool, plus the verify command for afterwards.
Feature additions, refactors, dependency upgrades, bug fixes — any change where “don't touch X” and “prove it works” matter.
vibe verify plan.json --repo . --json exits non-zero on any boundary violation or failed acceptance command.
Vibefiles are the shared protocol: a teammate's review of your change spec happens before any code is generated.
.vibe/changes/ history answers “why did this change, and who approved the boundary?” — forever.
No. Vibe's compiler and verifier contain zero AI. Vibe is the contract layer around AI code generation: it constrains what an agent may do and mechanically proves whether it did it. The agent is whichever tool you already use.
A prompt is advice; a Vibefile is enforcement. Even the best prompt can't guarantee an agent stays out of src/payments/ — the verifier checks the actual git diff after execution, and CI can refuse the merge. Prompts also can't be diffed, reviewed, or replayed six months later. Vibefiles can.
Engineers review and maintain them; assistants can draft them from natural language (roadmap: schema-constrained drafting built in). Same as SQL or Dockerfiles — most people don't write them from scratch, but the system would be unmanageable without them.
Anything with a CLI: Cursor's agent, Claude Code, aider, or a custom script. The executor is configured per repository as a command template. Vibe hands it a deterministic contract and judges the result.
Not by Vibe. The toolchain is fully local and deterministic. Only your chosen executor talks to a model — under whatever terms you already accepted for that tool.
Today they're emitted as a human checklist after each run; run commands are fully automated. Lowering behavioral checks to Playwright/E2E suites is the top roadmap item.