The Vibe Coder's Bible
Chapter 13

The Core Loop

Intent becomes real only after it crosses the commit boundary.

Chapter 13 - The Core Loop

Part: IV - The Propose / Validate / Commit Loop

Thesis

Propose, Validate, Commit is not only a vibe-coding technique. It is the shared control loop for building software with a model and for running a model inside software. At build time the loop runs once per session. At runtime it runs once per request, forever. Every failure - in AI-assisted development or in an AI-native application - traces back to the same skipped step: a proposal that crossed a commit boundary before it was validated.

Key Line

Intent becomes real only after it crosses the commit boundary.

The Three Phases

The loop has three phases and no shortcuts.

Propose. The model generates a candidate output - code, schema, migration, documentation, test, plan, or, if the model is running inside a live application, an action, a claim, a move, a piece of narration, a state patch. The proposal is cheap. It costs tokens and time, not judgment. A model that produces a wrong proposal has not caused harm. It has produced a proposal that will not survive validation.

Validate. Automated controls fire first. Tests run. The type checker runs. The linter runs. Schema validators run. What passes automated controls then reaches human review. The human is not reading raw model output. The human is reviewing output that has already survived the machine checks. Judgment lives in validation, not in the proposal. In a runtime system there is usually no human in that second layer - the equivalent controls are schema parsers, permission checks, and legality or domain rules, and they must fire on every request, because no one is standing by to catch what they miss.

Commit. The verified output crosses the boundary and becomes state. A commit is not a checkpoint. It is an explicit act of ownership. The developer who commits is saying: “I accept this output as correct.” That statement has weight. It should feel like weight. The boundary is not always a git commit. It is whatever transition turns a proposal into something persistent, public, executable, or user-visible - a merge, a database write, an executed tool call, a published sentence. The next section names the two boundaries this book returns to most.

The loop does not end. After a commit, the next feature, bug, request, or refactor starts a new iteration. The loop is the workflow, at build time and at runtime alike.

Propose

The proposal phase is the only phase where the model operates without constraint on output.

That is not a flaw. It is the point. The model generates broadly because broad generation is cheap to produce and cheap to filter. A model that generates three candidate implementations allows a developer to pick the best one. A model that generates one cautious implementation has already made a judgment call the developer did not authorize.

Proposals are not decisions. A file full of model-generated code sitting in a branch is not a software change. It is a collection of proposals waiting for validation. Treat them that way.

The failure mode in the proposal phase is not bad output. It is treating proposals as decisions. A developer who reads model output, nods approvingly, and commits without running tests has confused Propose with Commit. The loop collapsed.

Keep proposals small. A proposal that covers one function, one endpoint, one migration, or one behavior unit is verifiable. A proposal that covers thirty files is a project, not a proposal.

Validate

Validation has two layers. Both are required.

The first layer is automated. Tests, type checks, schema validation, lint rules - every engineering control defined in Chapter 10 belongs here. These controls fire before a human reads a line of the diff. They do not get tired. They do not grant exceptions because the deadline is close. They fire, and they either pass or fail.

The second layer is human review. The human reviews what passed automated controls. This is the correct framing. The human is not a backup to automation. The human is a second filter that runs on output automation already approved. That sequence matters. A human reviewing output that has already passed tests, types, and schema validation is doing higher-order work: checking intent, checking architecture, checking whether the code does what the commit message claims.

These two layers are not interchangeable. Running human review without automated controls first means the human is doing automation’s job on top of their own. Running automated controls without human review means intent is never checked. Both are required.

The output of a successful validation is permission to commit. Not confidence, not certainty - permission. The controls passed. The human is satisfied. The output may proceed.

Commit

The commit is not a save point. It is a statement.

When a developer runs git commit, they are declaring that the staged changes are correct, verified, and ready to become part of the project’s permanent record. That is a strong claim. It should be made deliberately.

Commit discipline in AI-assisted development is specific. The commit message explains why this change was made, not just what the diff contains. The message is written for the model that will read git log in the next session and need to understand the constraint that produced the decision.

Small commits are easier to verify, easier to revert, and easier to understand. A commit that covers one logical change allows a future reader to understand one decision. A commit that covers a session’s worth of output requires reconstructing the session from the diff.

The commit is also the point at which the developer accepts liability. Not legal liability. Professional liability. If the change breaks production, the commit author owns the investigation. That ownership is why the commit must follow validation, not precede it.

Two Commit Boundaries

“Commit,” so far, has meant one thing implicitly: a developer accepting output into the repository. That is one instance of a more general idea.

Introduction I names two places a model can stand: the build loop and the runtime loop. The Propose / Validate / Commit loop runs in both places, but the commit boundary means something different in each.

The development commit boundary is where generated code, tests, schemas, migrations, documentation, or configuration stops being a proposal and becomes repository or deployed software. The mechanism is usually a merge, a deploy, or a release. The clock is human-paced. A person decided.

The runtime commit boundary is where generated output stops being a draft and becomes database state, an executed tool action, a published claim, a legal move applied to a board, a rendered event, or any other truth a user can see or a system will act on. The mechanism is a write, an execution, a publish call, a state reducer accepting a patch. The clock is machine-paced. Whatever decides has to already be built into the system, because there is no person in the loop to ask before the next request arrives.

Both boundaries answer the same question: has this proposal earned the right to be treated as real? Neither boundary is git-specific. git commit is one implementation of a development commit boundary. It is not what “commit” means in this book.

Only validated state becomes real.

That line holds at both boundaries. A patch that has not passed tests and review is not code yet, no matter how correct it looks in the diff. A tool call that has not passed its schema, its permission check, and its domain rule is not an action yet, no matter how confident the model sounded producing it. Confidence is not validation. Only validation is validation.

The State-First Role Model

Both boundaries are staffed by the same seven roles, whether the system is a codebase or a running application.

RoleJobBuild-time instanceRuntime instance
GeneratorProduces a candidateThe model drafting a patch, a test, a migrationThe model drafting a tool call, a move, a claim, a narration
SpecificationShapes the proposal before it exists (ex ante)Prompt, CLAUDE.md, existing tests, schema in contextTool description, schema, retrieved state, current permissions
ValidatorChecks the proposal after it exists (ex post)Tests, type checker, linter, human reviewSchema parser, permission check, legality engine, solver
State substrateHolds what has already been acceptedThe repository - Chapter 14Database, event log, registry - Chapter 14
ReducerApplies an accepted proposal to stateMerge, migration runnerBoard-state reducer, ledger update, action executor
Renderer / exporterProduces what a person or downstream system seesBuild artifact, deployed releaseRendered UI, spoken narration, exported frame
TraceRecords what was proposed, accepted, and rejectedCommit log, CI history, PR thread - Chapter 17Tool-call log, rejection log, audit trail

Nothing in this table is optional in a system that takes model output seriously. A generator without a specification is guessing. A validator without a state substrate has nothing authoritative to check the proposal against. A reducer without a trace makes every accepted change unauditable. The table is not a menu. It is a minimum staff list.

One Loop, Two Boundaries: A Worked Comparison

Put a build-time proposal and a runtime proposal through the same loop, side by side.

StepBuild-time: a code patchRuntime: a tool action
IntentA developer wants to fix a bugA user’s request implies an action
Specification (ex ante)Prompt, CLAUDE.md, the failing test, existing codeTool description, schema, current game or account state, permissions
ProposalThe model drafts a diffThe model emits a typed tool call
Private eventCommit on a feature branchDraft tool call, not yet authorized
Validation (ex post)Tests, types, lint, human review of the diffSchema validation, permission check, domain-rule check
Commitgit merge to mainThe tool executes; a row is written or a state patch is applied
Rejected pathPR blocked; review comments explain whyCall rejected; structured error returned; attempt logged
Public / persistent eventMerged, deployed changeExecuted action, stored state, user-visible result
TraceCommit message, PR history, CI logTool-call log, rejection log, audit trail

Read the two columns against each other. Every row on the left has a row on the right. The steps do not change. The nouns do.

The private-event row matters most. A branch commit and a draft tool call are the same kind of thing - visible to the process that produced them, absent from anything anyone else depends on, cheap to discard. A merge to main and an executed tool call are also the same kind of thing - visible outside the process, expensive to take back, the difference Chapter 6 calls commit-level rather than generation-level failure when they turn out to be wrong. The discipline in this chapter is keeping proposals in the private lane until validation earns them a place in the public one.

The Inner Loop

Inside every Propose-Validate-Commit cycle, a tighter loop runs.

The developer reads the proposal. They find something wrong. They prompt the model to revise. The model revises. They read again. They accept or revise again. This is the inner loop: Propose -> Review -> Revise -> Accept.

The inner loop is where most of the work happens. The outer loop defines the boundary - what counts as done. The inner loop is where output improves before it reaches the boundary.

Inner loop hygiene: keep the inner loop short. A proposal that requires ten rounds of revision before it is acceptable is a signal that the initial prompt was underspecified. Revising the prompt costs one round. Revising the output ten times costs ten rounds. Spend the investment at the beginning, not throughout.

The inner loop does not substitute for the outer loop. A proposal that has been revised until the developer is satisfied has still only passed the human review layer of the inner loop. It has not passed automated controls. The outer loop’s validation layer still applies.

Runtime systems have an inner loop too, but it cannot lean on a human noticing something is off. The pattern is a bounded repair loop: a validator rejects a proposal, the system returns the precise error to the model - which field, which rule, which constraint - and the model gets one or two chances to produce a proposal that passes. That is different from blind resampling, where the model tries again with no new information and no better odds of passing. A repair loop that never terminates is not a control. It is a slower way of ignoring the validator. Chapter 16 treats this loop directly for schema failures.

Loop Hygiene

Loop hygiene is the discipline of keeping iterations small enough to complete quickly.

A loop that takes days to complete one iteration has broken feedback. The proposal from Monday is validated on Thursday. By Thursday, the developer’s memory of why the proposal was shaped that way has faded. The validation is slower and less sharp.

Aim for iterations that complete in hours. A session that produces a proposal in the morning and validates it before lunch has a tight loop. A session that produces a proposal Monday and validates it after the weekend review has a loose loop. Loose loops accumulate unvalidated output. Accumulated unvalidated output is technical risk.

The loop size discipline is:

Loop durationRisk levelRemedy
Under 2 hoursLowNormal operations
2 - 8 hoursMediumReview before the session ends
8 - 24 hoursHighDo not start a new proposal until prior one is committed
Over 24 hoursCriticalStop. Validate everything staged. Commit or discard.

Unvalidated output left overnight is output that will be validated under different conditions than it was generated. Context has shifted. Memory has degraded. The validation will be weaker.

When To Restart

Restart the session when accumulated unvalidated output exceeds what can be reviewed in a single sitting.

If a session has been running for five hours and the diff touches twelve files, the session has outrun the developer’s capacity for thorough review. Committing that output is not closing the loop. It is abandoning the validation phase and calling it done.

The correct response is to stop generating. Review the accumulated diff. Identify what can be committed now - the work that is complete and verifiable. Commit that. Discard or stash what cannot be verified yet. Start the next session with a clean branch.

This feels slow. It is not. The alternative - committing large unreviewed diffs - produces bugs that cost orders of magnitude more time to diagnose than the review would have taken.

A session restart is not a failure. It is the loop enforcing its own discipline.

Domain Map

The loop is domain-independent. Every AI-assisted change follows the same shape.

DomainProposalValidatorCommit
CodeDiffTests, types, lint, CIGit merge
DatabaseMigration scriptDry run, schema check, backupApply migration
APIContract or schema changeContract tests, client checksRelease endpoint
ContentDraftSource review, fact checkPublish
CalculationProblem interpretationDeterministic solver, unit systemRecorded result (ProveCalc)
Game moveProposed actionRules engine, dice systemMove applied to board or world state (RPG-MCP, LLM-Chess)
Civic claimNarration, briefing draftSource cards, provenance gatesPublic event promotion (Clio)
Video editState-patch proposalBase-hash check, import gateAccepted state pack (Semantic Video Studio)
Agent tool callTool invocationCapability policy, output schemaExecute

The columns are always the same. The contents change by domain. The discipline is constant: nothing in the Commit column until the Validator column passes. The worked comparison above unfolds this table’s Code and Agent tool call rows step by step; every other row follows the same shape.

Practical Artifact - Loop Health Check

Run this check at the end of every session, before closing the branch.

QuestionGreenRed
Is every proposed change covered by at least one automated validation?YesNo - validation gap
Did CI pass on the current branch?YesNo - do not commit
Was the diff read line by line before the PR was opened?YesNo - review debt
Is the commit message written for the next session, not just for today?YesNo - memory gap
Does the PR cover one logical change?YesNo - split the PR
Is the branch up to date with main?YesNo - merge conflict risk
Is there a handoff note if the session continues tomorrow?YesNo - context loss
If this system also runs at runtime, does every consequential proposal pass schema, permission, and domain validation before it commits?YesNo - runtime validation gap

A session with all green answers has closed the loop. A session with red answers has open loop items. Do not start the next proposal, and do not open the next runtime capability, until the red items are resolved.


Export

Copy this block into your CLAUDE.md, agent instructions, or project checklist.

Intent becomes real only after it crosses the commit boundary.

vcb_chapter: 13
title: "The Core Loop"
key_line: "Intent becomes real only after it crosses the commit boundary."
thesis: "Propose, Validate, Commit is the shared control loop for building software with a model and for running a model inside software. Only validated state becomes real."
checklist:
 - item: "Every proposal is scoped to one commit-boundary-sized unit - one logical change, or one action."
 protects: "Diffs or actions too large to validate thoroughly"
 - item: "Ex post validation - automated controls, or schema, permission, and domain checks - runs before anything crosses the commit boundary."
 protects: "Plausible-but-wrong output reaching state"
 - item: "Commit message or trace record explains why, not just what."
 protects: "Context loss between sessions or between requests"
 - item: "Session is restarted, or the runtime backlog is drained, when accumulated unvalidated output exceeds review capacity."
 protects: "Large unreviewed diffs or backlogged proposals crossing the commit boundary"
 - item: "Loop health check passes before the session closes, and every runtime validation gap is named and owned."
 protects: "Open loop items becoming the next session's, or the next request's, technical debt"
  • Is every proposal scoped to one commit-boundary-sized unit - one logical change, or one action? - Protects against diffs or actions too large for thorough validation
  • Did ex ante specification - prompt, schema, tool description, retrieved state - exist before the proposal was generated? - Protects against the model guessing at unstated rules
  • Did ex post validation - automated controls and review, or schema, permission, and domain checks - run before anything crossed the commit boundary? - Protects against plausible-but-wrong output becoming state
  • Does a durable record explain why this became state - a commit message, or a trace log entry? - Protects against context loss for the next session or the next request
  • Is there a place rejected proposals go, and would you notice if the rejection rate changed? - Protects against silent validation gaps

Practical Artifact

0/8 checked