Stop Prompting AI. Start Engineering Loops.
Tech

Stop Prompting AI. Start Engineering Loops.

By Ali Hamie·

For the last two years, we have been teaching people how to write better prompts.

Add more context. Be specific. Give the model a role. Ask it to think step by step. Include examples. Define the output format.

That advice helped when every interaction with AI started with an empty chat box.

But I do not think the future of AI assisted engineering is a developer sitting at a keyboard, lovingly crafting the perfect paragraph for every task.

The prompt should not be something you keep writing.

It should be something your system produces.

The next abstraction is not prompt engineering. It is loop engineering.

A Prompt Is an Instruction. A Loop Is a System.

A prompt tells an AI what to do once.

A loop decides what needs to be done, gathers the context, gives the AI its instructions, checks the result, and decides what should happen next.

That distinction sounds small until you see it running.

Imagine you maintain a GitHub repository with twelve open issues. In a prompt driven workflow, you do this:

  1. Open GitHub.
  2. Pick an issue.
  3. Copy its title and description.
  4. Open Codex.
  5. Explain the repository.
  6. Point it toward the likely files.
  7. Ask it to implement the fix.
  8. Run the tests.
  9. Paste the failure back into Codex.
  10. Ask it to fix the failure.
  11. Review the diff.
  12. Ask it to write the pull request description.

You are using AI, but you are still the workflow engine.

In a loop driven workflow, the system does the mechanical coordination:

Schedule → inspect issues → select work → gather context → implement → verify → review → publish or escalate → repeat

You stop translating work into prompts. You design the rules that perform the translation for you.

The Example We Are Going to Build

Let us use a fictional issue from a small TypeScript API.

Issue 184: Usernames with spaces return a server error

The issue description says:

Creating a user with a username that begins or ends with spaces returns a server error. We should trim the username before validation. If the trimmed username is empty, return a validation error. Please add tests.

This is a good candidate for autonomous work because it is bounded, reproducible, and testable. It does not require a product decision. It does not change authentication, billing, privacy, or infrastructure. Its acceptance criteria are clear.

We add the label agent ready.

That label is not a command to blindly change code. It means the issue is eligible to enter the loop.

Every morning, a scheduled Codex automation checks for open issues with that label. It does not simply choose the first one and start coding. It invokes two reusable skills.

The first skill triages the project.

The second orchestrates the work through completion.

The Three Layers of the Loop

Post content

The cleanest way to understand this system is to separate it into three layers.

1. The Scheduler

The scheduler decides when the loop wakes up.

It could run every weekday morning, every hour, or only when you trigger it manually. Frequency is not the interesting part. The scheduler should contain very little intelligence. Its job is to reenter the workflow consistently.

A useful automation instruction could be:

Every weekday at 8:00 AM, inspect the current GitHub repository for open issues labelled agent ready.

Use the project triage skill to evaluate the queue. Select no more than one autonomous issue. Then use the maintainer orchestration skill to take that issue through reproduction, implementation, verification, and pull request preparation.

Never merge automatically. Stop and report when the issue requires product judgment, credentials, security decisions, destructive actions, or verification that cannot be completed.

If no safe issue is available, report why and make no repository changes.

Notice what is missing. There is no issue number. There are no filenames. There is no implementation plan.

The automation prompt defines the loop, not the task. The task is discovered from live state when the loop runs.

2. The Triage Skill

The triage skill is the sensor and classifier.

It reads GitHub and answers a narrow question: what work is available, and which of it can be completed safely without human judgment?

A compact version of the skill could contain these instructions:

# GitHub Project Triage

Inspect open issues labelled agent ready.

For each issue, read the title, description, labels, comments, and linked pull requests. Read repository guidance before judging fit.

Classify each issue as autonomous, needs owner, or defer.

An autonomous issue must have a bounded scope, clear expected behaviour, a plausible reproduction path, and a usable verification path.

Issues involving security, privacy, credentials, billing, destructive migration, broad product behaviour, or unclear acceptance criteria need the owner.

Prefer bugs, documentation fixes, tests, and small internal improvements. Select no more than one issue.

Return the issue URL, why it qualifies, the expected proof, material risks, and the next action.

When the loop reads issue 184, it does not treat the description as truth. It treats it as a report that needs to be verified.

The triage result might look like this:

Issue 184 qualifies as autonomous.

Reason: The behaviour is narrow, the expected result is explicit, and the API has an existing user creation test suite.

Required proof: Reproduce the server error on the current default branch. Add coverage for leading spaces, trailing spaces, and an input containing only spaces. Run the focused user API tests and the full repository test command.

Risk: Low. The likely change is limited to username normalization and validation.

Next action: Hand issue 184 to the repository worker.

That output becomes input to the next stage. The loop has now generated most of the prompt a human would normally write.

3. The Orchestrator Skill

The orchestrator is the control plane.

It owns the state machine. It decides who performs the work, what must be true before the work begins, which gates must pass, and when to stop.

A compact version could say:

# Maintainer Orchestrator

Use one worker for the repository and process one issue at a time.

Before implementation, confirm the checkout is clean and synchronized with the current default branch. Preserve unexpected local work and stop rather than overwriting it.

Give the worker the selected issue, repository instructions, triage result, and required verification.

The worker must reproduce the problem before accepting the proposed diagnosis. It must inspect the relevant code, implement the smallest maintainable fix, add regression coverage, run focused checks, and run the repository verification commands.

If verification fails, use the failure output as context for the next attempt. Continue only while each attempt produces concrete progress.

When all required checks pass, prepare a pull request containing the issue link, root cause, implementation summary, exact tests, and remaining risks.

Never merge without explicit permission. Escalate product choices, security or privacy decisions, missing credentials, destructive actions, and unavailable live proof.

The skill is not a giant prompt for one bug. It is durable operating policy for every issue that enters the loop.

What Codex Receives

By the time the worker starts, its task can be assembled automatically from several sources:

  1. The GitHub issue provides the reported symptom and requested behaviour.
  2. The triage skill provides classification, risk, and required proof.
  3. Repository guidance provides local conventions and commands.
  4. The current codebase provides the implementation context.
  5. The orchestrator provides the process and stopping conditions.

The generated task might read like this:

Work on issue 184 in the current repository.

Reported behaviour: Creating a user with leading or trailing spaces in the username returns a server error.

Expected behaviour: Normalize the username before validation. Return a validation response when the normalized username is empty.

First reproduce the issue on the current default branch. Inspect repository guidance and the user creation path. Do not assume the issue's proposed fix is the correct root cause.

Implement a maintainable fix and add regression tests for leading spaces, trailing spaces, and whitespace only input.

Run the focused user API tests, then run the repository's full verification commands.

If verification succeeds, prepare a pull request that links issue 184 and documents the root cause, files changed, tests run, and any remaining risk. Do not merge.

Stop if the work expands into authentication policy, database migration, destructive changes, missing credentials, or unclear product behaviour.

This is a good prompt. But no person wrote it.

The loop composed it from the issue, repository, skills, and current environment.

That is the shift.

Verification Is What Makes It Engineering

An AI loop without verification is just a faster way to create unreviewed code.

The loop needs gates that are observable and difficult to argue with.

For issue 184, success should mean all of the following:

  1. The bug was reproduced before the fix.
  2. A regression test failed for the expected reason.
  3. The implementation fixed the test.
  4. Existing focused tests still passed.
  5. The full repository checks passed.
  6. The final diff stayed within the intended scope.
  7. The pull request explained what was proven and what was not.

The agent should not be allowed to replace a failed command with a confident paragraph.

If the test command fails, the failure becomes new context:

The focused test now passes, but the full test suite reports that usernames are also normalized in the account import path. Inspect whether the new helper should be shared or whether the import behaviour must remain unchanged. Do not weaken the existing test. Report if this reveals an unresolved product decision.

The output of one iteration becomes the input to the next.

That is why it is a loop rather than a pipeline. A pipeline follows a fixed sequence. A loop observes results and changes its next action.

The Loop Needs Terminal States

Post content

“Keep trying until it works” is not a serious operating model.

Every run should end in a known state.

Ready for review means the change is implemented, verification passed, and a pull request is prepared.

Needs owner means the remaining question requires product, security, privacy, credential, or destructive action authority.

Blocked means the required environment, service, hardware, or verification target is unavailable.

Rejected means the issue is not reproducible, is already fixed, duplicates other work, or does not fit the repository.

No work means there is no eligible issue.

These states matter because an autonomous system must know when not to act.

Why One Issue at a Time Matters

It is tempting to point the loop at twenty issues and celebrate the parallelism.

Start with one.

One issue gives you a clean causal chain. You know which change caused a failure. You know which branch owns the work. You know which tests apply. You can review one coherent pull request.

The production skill I used goes even further. It keeps one repository worker and lets that worker process the queue serially. The orchestration layer can watch many repositories, but each repository has a single owner for implementation.

This avoids two agents changing the same file, duplicating an issue, racing to update a branch, or interpreting the same repository state differently.

Concurrency is useful after ownership is clear. Before that, it is mostly a creative way to produce merge conflicts.

The Human Is Still in the Loop, Just at a Better Level

Loop engineering does not remove human judgment. It stops wasting human judgment on coordination.

You should not need to copy an issue into a chat box. You should not need to remind the agent to read the repository instructions. You should not need to paste a test failure back into the same conversation. You should not need to ask it to include the issue link in the pull request.

Those are deterministic workflow rules. Put them in the loop.

The human should decide whether a product behaviour is desirable, whether a security tradeoff is acceptable, whether a migration is worth the risk, and whether verified code should ship.

The loop handles motion. The human handles judgment.

How to Start Without Building a Monster

Do not begin with a system that can merge, deploy, publish releases, and update every repository you own.

Begin with a loop that can do four things well:

  1. Read issues with an explicit eligibility label.
  2. Select one issue with clear acceptance criteria.
  3. Implement and verify the change in an isolated branch.
  4. Prepare a pull request for human review.

Run it manually at first. Read every trace. Look for the places where you keep correcting the same behaviour.

When a correction is reusable, move it out of the chat and into repository guidance or a skill.

When the workflow becomes predictable, schedule it.

When verification becomes trustworthy, widen the set of eligible issues.

Autonomy should expand when evidence earns it.

The New Job Is Designing the Loop

Prompt engineering asks: what should I tell the model right now?

Loop engineering asks better questions.

What signals should wake the system up?

How does it choose work?

Which context is authoritative?

What can it change?

How does it prove the result?

What happens after failure?

When must it stop?

Where is human judgment actually valuable?

Those questions look less like chatting with an AI and more like designing software.

That is exactly the point.

The best prompt is not the paragraph you spent twenty minutes polishing.

It is the one your system assembled from the right context, at the right time, with the right verification, without asking you to write it at all.

References

This workflow was inspired by Peter Steinberger's Maintainer Orchestrator skill and GitHub Project Triage skill.

OpenAI documents scheduled Codex workflows in Codex Automations and provides related examples in the Codex use case library.

*Written by Ali Hamie, software engineer at Meta and founder of Bits & Bonds.*

Build the Complete Loop

Ready to implement it? Follow the complete, model agnostic guide: How to Build an AI Coding Loop That Turns GitHub Issues Into Pull Requests.

Keep reading

Newsletter

Get new posts in your inbox.

Finance and tech insights for Canadians — no spam, unsubscribe any time.