Guide to coding with AI assistants

#ai

AI-Assisted Development: Blog Post Plan

1) The enthusiastic junior developer, and why it matters (180–220 words)

Cover:

  • Open with the analogy: fast, keen, broad knowledge, weak project-specific understanding, confident tone.
  • Make the central claim: used well, AI can speed up delivery of routine engineering work, but it does not replace judgement.
  • State the practical implication: humans own scope, risk, review, and verification.

2) What this post covers: a workflow that makes speed safe (120–160 words)

Cover:

  • Introduce the Explore – Plan – Code – Verify loop as a lightweight control system around AI output.
  • Highlight the key technique: break work into atomic tasks with acceptance criteria, a definition of done, and manual tests where appropriate.

3) Failure modes: why a workflow is required (220–280 words)

Cover:

  • Hallucinated or outdated APIs, flags, configuration, and framework behaviour.
  • Scope creep: “helpful” refactors, formatting churn, renames, or dependency additions unrelated to the task.
  • Correct-looking code that misses edge cases, non-functional requirements, or integration boundaries.
  • Tests that pass but do not assert the intended behaviour.
  • Getting stuck in a bug-fixing loop: repeated patches without new information or a change in approach.
  • Transition: these are predictable, which is why a workflow and gates matter.

4) Workflow overview: Explore – Plan – Code – Verify (120–160 words)

Cover:

  • Explain each phase in one paragraph: what it does and what it produces.
  • Emphasise the rule: do not write code until verification is clear.
  • Explain cadence: the loop runs per atomic task and typically maps to a PR-sized change.

5) Explore: reduce ambiguity and confirm constraints (220–280 words)

Cover:

  • Inputs to gather: problem statement, expected behaviour, constraints (versions, environments, deployment), and relevant code paths.
  • Outputs to produce: clarified requirements, options and trade-offs, risks, unknowns to confirm.
  • Identify “stop and clarify” triggers: unclear requirements, data migrations, authZ boundaries, external API uncertainty, performance implications.
  • Aim for minimal-change thinking: prefer the smallest correct intervention.

6) Plan: atomic tasks with acceptance criteria and definition of done (300–360 words)

Cover:

  • Define atomic in operational terms: independently verifiable, revertible, and small enough to review confidently.
  • Describe a task card format:
    • Scope and non-goals
    • Acceptance criteria
    • Definition of done
    • Automated tests to add or update
    • Manual test steps
    • Rollback note
    • Risk level
  • Explain planning depth: fully detail the next milestone, keep later milestones coarse (agile planning).
  • Add guardrails: a “do not touch” list, dependency limits, and explicit avoidance of drive-by refactors.

7) Code: implement the task, but supervise the assistant (150–200 words)

Cover:

  • Keep the Code step plain: implement one planned task at a time.
  • Supervise output for scope creep: unrelated refactors, new dependencies, broad renames, or style churn.
  • Watch for bug-fixing loops; when stuck, return to Explore (new evidence, new hypothesis) rather than iterating blindly.
  • Keep changes reviewable: minimal diff, readable commits, tests included with the change.

8) Verify: layered checks that earn trust (300–360 words)

Cover:

  • Automated checks: unit and integration tests, linting, type checks, build steps.
  • Behavioural checks: manual test script, edge cases, failure paths, cross-browser or device where relevant.
  • Operational checks: error handling, logging, metrics, configuration, migrations and rollbacks.
  • Security checks: input validation, output encoding, authZ, secrets and logging hygiene, dependency scrutiny.
  • Include a compact checklist and tie verification effort to task size and risk.

9) Context management: control what the assistant sees and assumes (200–260 words)

Cover:

  • Explain why context is a first-class dependency: low-quality context produces plausible nonsense.
  • Recommend a task brief per atomic task: scope, constraints, non-goals, relevant files, commands to run, versions.
  • Encourage explicit assumptions: keep an “assumptions and decisions” note in the PR or task.
  • Mention repo guidance files (for example AGENTS.md or CLAUDE.md): coding standards, commands, boundaries, and review expectations.

10) Scaling the workflow: bugfix vs feature vs project (180–230 words)

Cover:

  • Bugfix: short Explore and Plan, strict Verify, tiny PRs; avoid broad refactors.
  • Feature: more Explore and Plan, staged delivery, feature flags where appropriate, more manual testing and stakeholder checks.
  • Project: discovery spikes, architectural decision records, migration and rollout planning, stronger review and verification gates.
  • Emphasise invariants: atomicity, explicit verification, and human review do not go away.

11) Conclusion: speed with a human in the loop (120–160 words)

Cover:

  • Reinforce the core idea: AI increases throughput, but it does not change accountability.
  • Summarise the practical recipe: atomic tasks + explicit verification + rigorous review.
  • State the non-negotiable: a human in the loop for requirements, boundaries, code review, and final verification.

Everyone and their dog are now using AI coding assistants to vibe code apps and websites, the vast majority of these are not going to make it off their local computers. Given a chance, AI coding assistants will happily write hundreds or thousands of lines of code. This code will be full of bugs and hallucinations. They are like a junior developer with too much knowledge who wants to impress you by showing how many lines of code they can produce. Having the assistant write tests will catch many of these issues, but bugs will remain; finding them all will take time and while debugging them you will likely find serious structural issues that will mean refactoring large sections of the code. To prevent this sort of thing we need to follow good software engineering principles and by constraining the AI assistant we can make it write better code in a more predictable way.

By following a workflow that ensures the changes required are broken into fully specified atomic tasks with acceptance criteria and tests and each task is verified by a human before the next task is implemented, we help ensure that the code produced is of a high quality.

Explore → plan → code → verify

This is a highly successful workflow for constraining an AI coding assistant and having it produce high quality code. With some tweaks, it can be applied to coding tasks of all sizes from small bug fixes, through new features in existing projects to entirely new projects.

In the explore phase you work with the AI to investigate possible solutions. When planning you take the best solution from the explore phase and break it down into phases/milestones and tasks. The code phase implements a single task, which is then verified to ensure it meets acceptance criteria and definition of done specified in the planning phase.

The key to the whole workflow is breaking things into atomic tasks.

flowchart TB
    A(["Bug, feature or project"]) --> B["**Explore**"]
    B --> C["Accepted solution"]
    C --> D["**Plan**"]
    D --> E1["Phase breakdown
    (for larger pieces of work)"]
    E1 --> E2["Task specification
    (for current phase)"]
    E2 --> F["**Code**"]
    F --> G["Code changes"]
    G --> H["**Verify**"]
    H --> I{"Acceptance 
    criteria met?"}
    I -- No --> F
    I -- Yes --> J["Commit changes"]
    J --> K{"Are there 
    more tasks?"}
    K -- No --> L{"Are there 
    more phases?"}
    K -- Yes --> F
    L -- No --> M(["Complete"])
    L -- Yes --> D

    C@{ shape: lean-r}
    E1@{ shape: lean-r}
    E2@{ shape: lean-r}
    G@{ shape: lean-r}
    J@{ shape: trap-t}

Explore

  • Provide a prompt describing the issue or feature using as much detail as possible and
  • Define acceptance criteria
  • Pass relevant files and messages to the assistant and
  • Use an AGENTS.md file for site
  • For bug fixes you can ask the assistant to create a test that fails due to the bug.

Plan

Before the assistant changes any files have list what it's going to do. Critique this plan closely. Ask if there are alternatives ways to achieve the same goal. If you don't understand why something is being done in a particular way ask it to explain it. Ensure things are broken down into atomic tasks with thier own tests and acceptance criteria For bigger bits of work have it save the plan so it can be referred back to in new seasons

Code

Tell the assistant to implement a single task with accompanying tests.

Verify

This is the most important part. Go through the code line by line, ensuring you understand what's going on. If you don't understand why something has been done in a particular way ask about it.

Git diffs are good for this, but it can be easier to use a merge request for the review. Check the tests are actually testing for the things you want. Ensure all automatic tests and linting checks pass. Manually test the changes to ensure you're happy with the way they work Using a separate ai agent to evaluate the changes can be good, but everything also needs to be manually verified as well.

Once you're happy the task ensure all the changes have been committed and move on to the next ta

Adjusting for size of the job

As

Best practices

Treat AI coding assistants as very enthusiastic junior developers who have a tendency to get carried away

AI assistants are eager, fast, and have broad knowledge, but they lack context about your specific codebase, business logic and the consequences of their suggestions. Assume it will confidently do the wrong thing unless constrained. You need to set boundaries, define done and verify.

Keep tasks small and atomic

The single most important practice is constraining scope. Each task should be the smallest viable change that is independently testable, reviewable, and deployable. Chunks of work larger than this should be broken down into a series of tasks. Once a task has been manually verified, commit the changes and move on to the next one.

Use an explore, plan, code, verify workflow

While the details will change depending on the size of what you're trying to achieve, the core workflow remains the same.

Each step will involve a dialogue with the assistant as you refine the outputs until you're happy with them.

Define acceptance criteria before you ask for code

Make the AI propose a plan before it writes code

Verify with diffs and merge requests

Provide Rich Context

AI assistants don't know your coding standards, your team's conventions, or why that seemingly redundant validation exists. Before asking for code, briefly explain the context: what the code needs to do, what constraints exist, what patterns you're already using. "We're using dependency injection throughout this project" or "this needs to work with PHP 8.1" saves a lot of back-and-forth.

Use an AGENTS.md file to provide information about the project and the tools and standards used

Symlink AGENTS.md to CALUDE.md so the same file can be used by Claude Code and other AI agents.


Links

  • [[2025-W52]]