An engineering workflow, not a snippet collection
How I use ChatGPT to produce code I can still explain and maintain
The model becomes more useful when it receives a bounded task, repository evidence and executable checks. It becomes dangerous when fluent output is mistaken for verified software.
I do not begin a coding request with 'build this app.' I begin with the smallest behaviour that can be specified and tested. I provide the relevant interfaces, runtime, constraints, existing pattern and acceptance criteria. That context is often the difference between a useful patch and code that merely looks familiar.
Generated code is a proposal. It may call an obsolete API, misunderstand local conventions, skip an authorization boundary or pass the happy path while failing in production. The developer remains responsible for reading the diff, running checks and understanding the failure modes.
Give the model a context packet
Include language and versions, the relevant files, nearby patterns, exact error output and commands that define success. Remove secrets and unrelated code. A smaller accurate packet usually beats a huge undirected dump.
Specify behaviour before implementation
State inputs, outputs, edge cases, error behaviour, performance constraints and what must not change. Ask for ambiguities before code. This converts the conversation from autocomplete into a reviewable engineering task.
Request the smallest coherent diff
Large rewrites hide mistakes and collide with active work. Ask which files need to change, keep public contracts stable where possible and split migrations from behavioural changes.
Make tests part of the request
Ask for a failing test or explicit acceptance check before implementation. Tests should include boundaries and failure conditions, not simply mirror the generated function.
Treat security as a design input
Name the trust boundary, authentication assumptions, authorization rule, data sensitivity and likely abuse cases. A late prompt asking to 'make it secure' cannot repair a confused design.
Ask for evidence, not confidence
Require the model to cite the exact code path behind a diagnosis, list assumptions and distinguish observed facts from hypotheses. Then verify against documentation and the running system.
My code-generation loop
- 1
Orient
Do: Read the entry point, tests, types and one analogous implementation before prompting.
Example: For a new API route, include the neighbouring route, validation helper and error-response convention.
Checkpoint: The request names the existing pattern.
- 2
Define acceptance
Do: Write observable requirements and exclusions.
Example: A duplicate request returns the existing resource, unauthenticated calls return 401, and no database schema changes are allowed.
Checkpoint: A reviewer can tell whether the task is done.
- 3
Plan the diff
Do: Ask for affected files, risk points and test cases before code.
Example: Challenge any proposed new abstraction that the repository does not need.
Checkpoint: The plan fits the ownership boundaries.
- 4
Generate one slice
Do: Implement the smallest end-to-end behaviour and keep the patch easy to inspect.
Example: Add validation and its tests before adding background processing.
Checkpoint: The diff has one clear purpose.
- 5
Run and diagnose
Do: Use formatter, type checker, focused tests and the real application path.
Example: Return the exact stack trace and environment details, not a paraphrase of 'it failed.'
Checkpoint: The claimed result is reproduced locally.
- 6
Review like unfamiliar code
Do: Inspect data flow, permissions, concurrency, cleanup, logging and rollback.
Example: Ask what happens when two requests race or a downstream call times out.
Checkpoint: You can explain every changed line.
Where AI-assisted coding goes wrong
Pasting secrets
Use placeholders and follow the organisation's data policy. Logs, tokens and customer data do not belong in an unapproved prompt.
Accepting invented APIs
Verify library methods and version compatibility in primary documentation or local types.
Skipping repository conventions
A technically valid solution can still duplicate helpers, bypass middleware or break observability.
Generating tests after the answer
Tests written to agree with an implementation may preserve the same misunderstanding. Start from behaviour.
Refactoring during a bug fix
Unrelated cleanup increases the review surface and makes regressions harder to isolate.
Letting comments claim correctness
A comment saying input is validated is not evidence. Trace the actual boundary and run adversarial cases.
Prompts I use in real code review
Repository-aware implementation
Implement this acceptance criterion using the existing patterns in the files below. First list assumptions and affected files. Keep the diff minimal, preserve public behaviour not named in the request, add focused tests, and do not invent dependencies. [CONTEXT] [CRITERIA]
Best after reading the local pattern yourself.
Root-cause debugger
Separate observed facts from hypotheses. Trace the error from entry point to failure using the stack trace and code supplied. Rank possible causes, name the evidence for each, and propose the smallest experiment that would disprove the leading cause before suggesting a fix.
This discourages random patching.
Adversarial review
Review this diff for broken authorization, unsafe input handling, races, resource leaks, incorrect error semantics, migration risk and missing tests. Cite the relevant line or path for every finding. Say when evidence is insufficient.
Run after the normal tests pass.
Refactor guardrail
Propose a staged refactor that preserves behaviour. Identify the characterization tests needed first, the smallest extraction boundary, and a rollback point. Do not combine formatting churn with behavioural changes.
Useful for legacy modules.
Reader workbook
Working notes for how i use chatgpt to produce code i can still explain and maintain
Reading the guide is only the first pass. The notes below turn its recommendations into evidence you can inspect, discuss with another person, and revise. Complete them with real material from your situation. Do not let an AI assistant fill gaps with plausible facts. When a policy, price, specification, source, system state, or personal experience matters, open the authoritative record and put the verified detail in your working document.
Working note 1: Give the model a context packet
Begin with a concrete example from the last thirty days. Record what happened, what information was available at the time, who made the decision, and what the result was. Then apply the principle above to that example. The useful output is not a general agreement that the principle sounds sensible; it is one changed action, one piece of evidence you will collect, and one condition that would make you choose a different approach. Write those three items in language another person could audit.
Evidence to leave behind
A dated note that connects βGive the model a context packetβ to one actual decision, names the evidence used, records uncertainty, and identifies the next person or check required before the decision becomes final.
Working note 2: Specify behaviour before implementation
Test this principle against a difficult case rather than the easiest one. List the constraint most likely to be ignored, the person who carries the downside if the advice is wrong, and the source that can settle a factual disagreement. Next, describe a small trial that is reversible and produces a visible result. Decide in advance what would count as improvement, no change, or harm. This turns a broad recommendation into a decision with limits instead of another optimistic intention.
Evidence to leave behind
A dated note that connects βSpecify behaviour before implementationβ to one actual decision, names the evidence used, records uncertainty, and identifies the next person or check required before the decision becomes final.
Working note 3: Request the smallest coherent diff
Explain this idea to a colleague, teacher, adviser, reviewer, or teammate without using jargon. Ask them where the explanation assumes knowledge that has not been demonstrated. Add the missing source, example, calculation, test, or observation. Finally, write the strongest reasonable objection and a response that acknowledges the trade-off. If the response depends on a vendor claim or an AI answer, mark it unverified until it has been checked against a primary source or real result.
Evidence to leave behind
A dated note that connects βRequest the smallest coherent diffβ to one actual decision, names the evidence used, records uncertainty, and identifies the next person or check required before the decision becomes final.
Working note 4: Make tests part of the request
Begin with a concrete example from the last thirty days. Record what happened, what information was available at the time, who made the decision, and what the result was. Then apply the principle above to that example. The useful output is not a general agreement that the principle sounds sensible; it is one changed action, one piece of evidence you will collect, and one condition that would make you choose a different approach. Write those three items in language another person could audit.
Evidence to leave behind
A dated note that connects βMake tests part of the requestβ to one actual decision, names the evidence used, records uncertainty, and identifies the next person or check required before the decision becomes final.
Working note 5: Treat security as a design input
Test this principle against a difficult case rather than the easiest one. List the constraint most likely to be ignored, the person who carries the downside if the advice is wrong, and the source that can settle a factual disagreement. Next, describe a small trial that is reversible and produces a visible result. Decide in advance what would count as improvement, no change, or harm. This turns a broad recommendation into a decision with limits instead of another optimistic intention.
Evidence to leave behind
A dated note that connects βTreat security as a design inputβ to one actual decision, names the evidence used, records uncertainty, and identifies the next person or check required before the decision becomes final.
Working note 6: Ask for evidence, not confidence
Explain this idea to a colleague, teacher, adviser, reviewer, or teammate without using jargon. Ask them where the explanation assumes knowledge that has not been demonstrated. Add the missing source, example, calculation, test, or observation. Finally, write the strongest reasonable objection and a response that acknowledges the trade-off. If the response depends on a vendor claim or an AI answer, mark it unverified until it has been checked against a primary source or real result.
Evidence to leave behind
A dated note that connects βAsk for evidence, not confidenceβ to one actual decision, names the evidence used, records uncertainty, and identifies the next person or check required before the decision becomes final.
A review record for my code-generation loop
Keep one row for every pass through the workflow. The record should make progress and failure equally easy to see. A polished output with no trace of its sources, assumptions, checks, or human decisions is difficult to improve and dangerous to trust. The following review questions are deliberately tied to the steps above.
After step 1
Review βOrientβ
Record what you actually did, not what the plan said you would do. Attach the relevant output or source. Use this checkpoint as the acceptance test: The request names the existing pattern. If it is not met, note whether the cause was missing information, weak skill, unclear ownership, insufficient time, a faulty assumption, or an external constraint. Choose one correction and repeat the smallest affected step rather than restarting the entire workflow.
After step 2
Review βDefine acceptanceβ
Record what you actually did, not what the plan said you would do. Attach the relevant output or source. Use this checkpoint as the acceptance test: A reviewer can tell whether the task is done. If it is not met, note whether the cause was missing information, weak skill, unclear ownership, insufficient time, a faulty assumption, or an external constraint. Choose one correction and repeat the smallest affected step rather than restarting the entire workflow.
After step 3
Review βPlan the diffβ
Record what you actually did, not what the plan said you would do. Attach the relevant output or source. Use this checkpoint as the acceptance test: The plan fits the ownership boundaries. If it is not met, note whether the cause was missing information, weak skill, unclear ownership, insufficient time, a faulty assumption, or an external constraint. Choose one correction and repeat the smallest affected step rather than restarting the entire workflow.
After step 4
Review βGenerate one sliceβ
Record what you actually did, not what the plan said you would do. Attach the relevant output or source. Use this checkpoint as the acceptance test: The diff has one clear purpose. If it is not met, note whether the cause was missing information, weak skill, unclear ownership, insufficient time, a faulty assumption, or an external constraint. Choose one correction and repeat the smallest affected step rather than restarting the entire workflow.
After step 5
Review βRun and diagnoseβ
Record what you actually did, not what the plan said you would do. Attach the relevant output or source. Use this checkpoint as the acceptance test: The claimed result is reproduced locally. If it is not met, note whether the cause was missing information, weak skill, unclear ownership, insufficient time, a faulty assumption, or an external constraint. Choose one correction and repeat the smallest affected step rather than restarting the entire workflow.
After step 6
Review βReview like unfamiliar codeβ
Record what you actually did, not what the plan said you would do. Attach the relevant output or source. Use this checkpoint as the acceptance test: You can explain every changed line. If it is not met, note whether the cause was missing information, weak skill, unclear ownership, insufficient time, a faulty assumption, or an external constraint. Choose one correction and repeat the smallest affected step rather than restarting the entire workflow.
A red-team pass before you rely on the result
Use the failure modes from this guide as a final challenge, not as a warning box you read and forget. Assign each one to a reviewer, or take them one at a time yourself. The reviewer should point to evidence in the work and should be allowed to say that the evidence is insufficient.
Could βPasting secretsβ be happening here?
Find the strongest sign that it is, then the strongest sign that it is not. Do not accept confidence, fluent wording, a high score, or a successful first attempt as proof. Write the additional check that would change the decision and name who owns that check.
Could βAccepting invented APIsβ be happening here?
Find the strongest sign that it is, then the strongest sign that it is not. Do not accept confidence, fluent wording, a high score, or a successful first attempt as proof. Write the additional check that would change the decision and name who owns that check.
Could βSkipping repository conventionsβ be happening here?
Find the strongest sign that it is, then the strongest sign that it is not. Do not accept confidence, fluent wording, a high score, or a successful first attempt as proof. Write the additional check that would change the decision and name who owns that check.
Could βGenerating tests after the answerβ be happening here?
Find the strongest sign that it is, then the strongest sign that it is not. Do not accept confidence, fluent wording, a high score, or a successful first attempt as proof. Write the additional check that would change the decision and name who owns that check.
Could βRefactoring during a bug fixβ be happening here?
Find the strongest sign that it is, then the strongest sign that it is not. Do not accept confidence, fluent wording, a high score, or a successful first attempt as proof. Write the additional check that would change the decision and name who owns that check.
Could βLetting comments claim correctnessβ be happening here?
Find the strongest sign that it is, then the strongest sign that it is not. Do not accept confidence, fluent wording, a high score, or a successful first attempt as proof. Write the additional check that would change the decision and name who owns that check.
How to use the prompts without outsourcing judgment
Before running any prompt, replace every placeholder, remove private information that is not required, and state which supplied sources the assistant may use. Save the initial input, output, corrections, and final human decision. This creates a record of how the tool contributed and makes it easier to spot when a later answer contradicts an earlier assumption.
- Repository-aware implementation: define the expected output before sending it, verify every material claim afterwards, and use this practical boundary: Best after reading the local pattern yourself.
- Root-cause debugger: define the expected output before sending it, verify every material claim afterwards, and use this practical boundary: This discourages random patching.
- Adversarial review: define the expected output before sending it, verify every material claim afterwards, and use this practical boundary: Run after the normal tests pass.
- Refactor guardrail: define the expected output before sending it, verify every material claim afterwards, and use this practical boundary: Useful for legacy modules.
End by writing a short decision note in your own words: what you learned, what remains uncertain, which source or test carries the most weight, what you decided, and when the decision should be reviewed. That note is often more valuable than the original AI output because it captures accountable judgment rather than a temporary answer.
The standard for accepting generated code
I accept the patch only when it matches the repository, passes the relevant checks and can be explained without asking the model. The goal is not maximum code per prompt; it is shorter feedback loops with maintained accountability.
When the task is ambiguous, the most productive output may be a question, a test or a failed hypothesis. Those are engineering progress too.
Primary sources checked