<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom"><title>Simon Willison's Weblog: code-review</title><link href="http://simonwillison.net/" rel="alternate"/><link href="http://simonwillison.net/tags/code-review.atom" rel="self"/><id>http://simonwillison.net/</id><updated>2026-03-04T17:34:42+00:00</updated><author><name>Simon Willison</name></author><entry><title>Anti-patterns: things to avoid</title><link href="https://simonwillison.net/guides/agentic-engineering-patterns/anti-patterns/" rel="alternate"/><published>2026-03-04T17:34:42+00:00</published><updated>2026-03-04T17:34:42+00:00</updated><id>https://simonwillison.net/guides/agentic-engineering-patterns/anti-patterns/</id><summary type="html">
    &lt;p&gt;&lt;em&gt;&lt;a href="https://simonwillison.net/guides/agentic-engineering-patterns/"&gt;Agentic Engineering Patterns&lt;/a&gt; &amp;gt;&lt;/em&gt;&lt;/p&gt;
    &lt;p&gt;There are some behaviors that are anti-patterns in our weird new world of agentic engineering.&lt;/p&gt;
&lt;h2 id="inflicting-unreviewed-code-on-collaborators"&gt;Inflicting unreviewed code on collaborators&lt;/h2&gt;
&lt;p&gt;This anti-pattern is common and deeply frustrating.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Don't file pull requests with code you haven't reviewed yourself&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;If you open a PR with hundreds (or thousands) of lines of code that an agent produced for you, and you haven't done the work to ensure that code is functional yourself, you are delegating the actual work to other people.&lt;/p&gt;
&lt;p&gt;They could have prompted an agent themselves. What value are you even providing?&lt;/p&gt;
&lt;p&gt;If you put code up for review you need to be confident that it's ready for other people to spend their time on it. The initial review pass is your responsibility, not something you should farm out to others.&lt;/p&gt;
&lt;p&gt;A good agentic engineering pull request has the following characteristics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The code works, and you are confident that it works. &lt;a href="https://simonwillison.net/2025/Dec/18/code-proven-to-work/"&gt;Your job is to deliver code that works&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The change is small enough to be reviewed efficiently without inflicting too much additional cognitive load on the reviewer. Several small PRs beats one big one, and splitting code into separate commits is easy with a coding agent to do the Git finagling for you.&lt;/li&gt;
&lt;li&gt;The PR includes additional context to help explain the change. What's the higher level goal that the change serves? Linking to relevant issues or specifications is useful here.&lt;/li&gt;
&lt;li&gt;Agents write convincing looking pull request descriptions. You need to review these too! It's rude to expect someone else to read text that you haven't read and validated yourself.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Given how easy it is to dump unreviewed code on other people, I recommend including some form of evidence that you've put that extra work in yourself. Notes on how you manually tested it, comments on specific implementation choices or even screenshots and video of the feature working go a &lt;em&gt;long&lt;/em&gt; way to demonstrating that a reviewer's time will not be wasted digging into the details.&lt;/p&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-ethics"&gt;ai-ethics&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/coding-agents"&gt;coding-agents&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-assisted-programming"&gt;ai-assisted-programming&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/agentic-engineering"&gt;agentic-engineering&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/code-review"&gt;code-review&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="ai"/><category term="llms"/><category term="ai-ethics"/><category term="coding-agents"/><category term="ai-assisted-programming"/><category term="generative-ai"/><category term="agentic-engineering"/><category term="code-review"/></entry><entry><title>Quoting Simon Højberg</title><link href="https://simonwillison.net/2025/Oct/8/simon-hojberg/" rel="alternate"/><published>2025-10-08T18:08:32+00:00</published><updated>2025-10-08T18:08:32+00:00</updated><id>https://simonwillison.net/2025/Oct/8/simon-hojberg/</id><summary type="html">
    &lt;blockquote cite="https://hojberg.xyz/the-programmer-identity-crisis/"&gt;&lt;p&gt;The cognitive debt of LLM-laden coding extends beyond disengagement of our craft. We’ve all heard the stories. Hyped up, vibed up, slop-jockeys with attention spans shorter than the framework-hopping JavaScript devs of the early 2010s, sling their sludge in pull requests and design docs, discouraging collaboration and disrupting teams. Code reviewing coworkers are rapidly losing their minds as they come to the crushing realization that they are now the first layer of quality control instead of one of the last. Asked to review; forced to pick apart. Calling out freshly added functions that are never called, hallucinated library additions, and obvious runtime or compilation errors. All while the author—who clearly only skimmed their “own” code—is taking no responsibility, going “whoopsie, Claude wrote that. Silly AI, ha-ha.”&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="cite"&gt;&amp;mdash; &lt;a href="https://hojberg.xyz/the-programmer-identity-crisis/"&gt;Simon Højberg&lt;/a&gt;, The Programmer Identity Crisis&lt;/p&gt;

    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/code-review"&gt;code-review&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-ethics"&gt;ai-ethics&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-misuse"&gt;ai-misuse&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/cognitive-debt"&gt;cognitive-debt&lt;/a&gt;&lt;/p&gt;



</summary><category term="code-review"/><category term="ai"/><category term="generative-ai"/><category term="llms"/><category term="ai-ethics"/><category term="ai-misuse"/><category term="cognitive-debt"/></entry><entry><title>Vibe engineering</title><link href="https://simonwillison.net/2025/Oct/7/vibe-engineering/" rel="alternate"/><published>2025-10-07T14:32:25+00:00</published><updated>2025-10-07T14:32:25+00:00</updated><id>https://simonwillison.net/2025/Oct/7/vibe-engineering/</id><summary type="html">
    &lt;p&gt;I feel like &lt;strong&gt;vibe coding&lt;/strong&gt; is &lt;a href="https://simonwillison.net/2025/Mar/19/vibe-coding/"&gt;pretty well established now&lt;/a&gt; as covering the fast, loose and irresponsible way of building software with AI - entirely prompt-driven, and with no attention paid to how the code actually works. This leaves us with a terminology gap: what should we call the other end of the spectrum, where seasoned professionals accelerate their work with LLMs while staying proudly and confidently accountable for the software they produce?&lt;/p&gt;
&lt;p&gt;I propose we call this &lt;strong&gt;vibe engineering&lt;/strong&gt;, with my tongue only partially in my cheek.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Update 23rd February 2026&lt;/strong&gt;: It looks like the term "Agentic Engineering" is coming out on top for this now. I have &lt;a href="https://simonwillison.net/tags/agentic-engineering/"&gt;a new tag for that&lt;/a&gt; and I'm working on &lt;a href="https://simonwillison.net/2026/Feb/23/agentic-engineering-patterns/"&gt;a not-quite-a-book&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;One of the lesser spoken truths of working productively with LLMs as a software engineer on non-toy-projects is that it's &lt;em&gt;difficult&lt;/em&gt;. There's a lot of depth to understanding how to use the tools, there are plenty of traps to avoid, and the pace at which they can churn out working code raises the bar for what the human participant can and should be contributing.&lt;/p&gt;
&lt;p&gt;The rise of &lt;strong&gt;coding agents&lt;/strong&gt; - tools like &lt;a href="https://www.claude.com/product/claude-code"&gt;Claude Code&lt;/a&gt; (released February 2025), OpenAI's &lt;a href="https://github.com/openai/codex"&gt;Codex CLI&lt;/a&gt; (April) and &lt;a href="https://github.com/google-gemini/gemini-cli"&gt;Gemini CLI&lt;/a&gt; (June) that can iterate on code, actively testing and modifying it until it achieves a specified goal, has dramatically increased the usefulness of LLMs for real-world coding problems.&lt;/p&gt;
&lt;p&gt;I'm increasingly hearing from experienced, credible software engineers who are running multiple copies of agents at once, tackling several problems in parallel and expanding the scope of what they can take on. I was skeptical of this at first but &lt;a href="https://simonwillison.net/2025/Oct/5/parallel-coding-agents/"&gt;I've started running multiple agents myself now&lt;/a&gt; and it's surprisingly effective, if mentally exhausting!&lt;/p&gt;
&lt;p&gt;This feels very different from classic vibe coding, where I outsource a simple, low-stakes task to an LLM and accept the result if it appears to work. Most of my &lt;a href="https://tools.simonwillison.net/"&gt;tools.simonwillison.net&lt;/a&gt; collection (&lt;a href="https://simonwillison.net/2025/Sep/4/highlighted-tools/"&gt;previously&lt;/a&gt;) were built like that. Iterating with coding agents to produce production-quality code that I'm confident I can maintain in the future feels like a different process entirely.&lt;/p&gt;
&lt;p&gt;It's also become clear to me that LLMs actively reward existing top tier software engineering practices:&lt;/p&gt;
&lt;ul id="techniques"&gt;
&lt;li&gt;
&lt;strong&gt;Automated testing&lt;/strong&gt;. If your project has a robust, comprehensive and stable test suite agentic coding tools can &lt;em&gt;fly&lt;/em&gt; with it. Without tests? Your agent might claim something works without having actually tested it at all, plus any new change could break an unrelated feature without you realizing it. Test-first development is particularly effective with agents that can iterate in a loop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Planning in advance&lt;/strong&gt;. Sitting down to hack something together goes much better if you start with a high level plan. Working with an agent makes this even more important - you can iterate on the plan first, then hand it off to the agent to write the code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comprehensive documentation&lt;/strong&gt;. Just like human programmers, an LLM can only keep a subset of the codebase in its context at once. Being able to feed in relevant documentation lets it use APIs from other areas without reading the code first. Write good documentation first and the model may be able to build the matching implementation from that input alone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Good version control habits&lt;/strong&gt;. Being able to undo mistakes and understand when and how something was changed is even more important when a coding agent might have made the changes. LLMs are also fiercely competent at Git - they can navigate the history themselves to track down the origin of bugs, and they're better than most developers at using &lt;a href="https://til.simonwillison.net/git/git-bisect"&gt;git bisect&lt;/a&gt;. Use that to your advantage.&lt;/li&gt;
&lt;li&gt;Having &lt;strong&gt;effective automation&lt;/strong&gt; in place. Continuous integration, automated formatting and linting, continuous deployment to a preview environment - all things that agentic coding tools can benefit from too. LLMs make writing quick automation scripts easier as well, which can help them then repeat tasks accurately and consistently next time.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;culture of code review&lt;/strong&gt;. This one explains itself. If you're fast and productive at code review you're going to have a much better time working with LLMs than if you'd rather write code yourself than review the same thing written by someone (or something) else.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;very weird form of management&lt;/strong&gt;. Getting good results out of a coding agent feels uncomfortably close to getting good results out of a human collaborator. You need to provide clear instructions, ensure they have the necessary context and provide actionable feedback on what they produce. It's a &lt;em&gt;lot&lt;/em&gt; easier than working with actual people because you don't have to worry about offending or discouraging them - but any existing management experience you have will prove surprisingly useful.&lt;/li&gt;
&lt;li&gt;Really good &lt;strong&gt;manual QA (quality assurance)&lt;/strong&gt;. Beyond automated tests, you need to be really good at manually testing software, including predicting and digging into edge-cases.&lt;/li&gt;
&lt;li&gt;Strong &lt;strong&gt;research skills&lt;/strong&gt;. There are dozens of ways to solve any given coding problem. Figuring out the best options and proving an approach has always been important, and remains a blocker on unleashing an agent to write the actual code.&lt;/li&gt;
&lt;li&gt;The ability to &lt;strong&gt;ship to a preview environment&lt;/strong&gt;. If an agent builds a feature, having a way to safely preview that feature (without deploying it straight to production) makes reviews much more productive and greatly reduces the risk of shipping something broken.&lt;/li&gt;
&lt;li&gt;An instinct for &lt;strong&gt;what can be outsourced&lt;/strong&gt; to AI and what you need to manually handle yourself. This is constantly evolving as the models and tools become more effective. A big part of working effectively with LLMs is maintaining a strong intuition for when they can best be applied.&lt;/li&gt;
&lt;li&gt;An updated &lt;strong&gt;sense of estimation&lt;/strong&gt;. Estimating how long a project will take has always been one of the hardest but most important parts of being a senior engineer, especially in organizations where budget and strategy decisions are made based on those estimates. AI-assisted coding makes this &lt;em&gt;even harder&lt;/em&gt; - things that used to take a long time are much faster, but estimations now depend on new factors which we're all still trying to figure out.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you're going to really exploit the capabilities of these new tools, you need to be operating &lt;em&gt;at the top of your game&lt;/em&gt;. You're not just responsible for writing the code - you're researching approaches, deciding on high-level architecture, writing specifications, defining success criteria, &lt;a href="https://simonwillison.net/2025/Sep/30/designing-agentic-loops/"&gt;designing agentic loops&lt;/a&gt;, planning QA, managing a growing army of weird digital interns who will absolutely cheat if you give them a chance, and spending &lt;em&gt;so much time on code review&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Almost all of these are characteristics of senior software engineers already!&lt;/p&gt;
&lt;p&gt;AI tools &lt;strong&gt;amplify existing expertise&lt;/strong&gt;. The more skills and experience you have as a software engineer the faster and better the results you can get from working with LLMs and coding agents.&lt;/p&gt;
&lt;h4 id="-vibe-engineering-really-"&gt;"Vibe engineering", really?&lt;/h4&gt;
&lt;p&gt;Is this a stupid name? Yeah, probably. "Vibes" as a concept in AI feels a little tired at this point. "Vibe coding" itself is used by a lot of developers in a dismissive way. I'm ready to reclaim vibes for something more constructive.&lt;/p&gt;
&lt;p&gt;I've never really liked the artificial distinction between "coders" and "engineers" - that's always smelled to me a bit like gatekeeping. But in this case a bit of gatekeeping is exactly what we need!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Vibe engineering&lt;/strong&gt; establishes a clear distinction from vibe coding. It signals that this is a different, harder and more sophisticated way of working with AI tools to build production software.&lt;/p&gt;
&lt;p&gt;I like that this is cheeky and likely to be controversial. This whole space is still absurd in all sorts of different ways. We shouldn't take ourselves too seriously while we figure out the most productive ways to apply these new tools.&lt;/p&gt;
&lt;p&gt;I've tried in the past to get terms like &lt;strong&gt;&lt;a href="https://simonwillison.net/tags/ai-assisted-programming/"&gt;AI-assisted programming&lt;/a&gt;&lt;/strong&gt; to stick, with approximately zero success. May as well try rubbing some vibes on it and see what happens.&lt;/p&gt;
&lt;p&gt;I also really like the clear mismatch between "vibes" and "engineering". It makes the combined term self-contradictory in a way that I find mischievous and (hopefully) sticky.&lt;/p&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/code-review"&gt;code-review&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/definitions"&gt;definitions&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/software-engineering"&gt;software-engineering&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-assisted-programming"&gt;ai-assisted-programming&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/vibe-coding"&gt;vibe-coding&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/coding-agents"&gt;coding-agents&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/parallel-agents"&gt;parallel-agents&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/agentic-engineering"&gt;agentic-engineering&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="code-review"/><category term="definitions"/><category term="software-engineering"/><category term="ai"/><category term="generative-ai"/><category term="llms"/><category term="ai-assisted-programming"/><category term="vibe-coding"/><category term="coding-agents"/><category term="parallel-agents"/><category term="agentic-engineering"/></entry><entry><title>GPT‑5-Codex and upgrades to Codex</title><link href="https://simonwillison.net/2025/Sep/15/gpt-5-codex/" rel="alternate"/><published>2025-09-15T18:55:35+00:00</published><updated>2025-09-15T18:55:35+00:00</updated><id>https://simonwillison.net/2025/Sep/15/gpt-5-codex/</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://openai.com/index/introducing-upgrades-to-codex/"&gt;GPT‑5-Codex and upgrades to Codex&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
OpenAI half-released a new model today: GPT‑5-Codex, a fine-tuned GPT-5 variant explicitly designed for their various AI-assisted programming tools.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Update&lt;/strong&gt;: OpenAI call it a "version of GPT-5", they don't explicitly describe it as a fine-tuned model. Calling it a fine-tune was my mistake here. &lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I say half-released because it's not yet available via their API, but they "plan to make GPT‑5-Codex available in the API soon".&lt;/p&gt;
&lt;p&gt;I wrote about &lt;a href="https://simonwillison.net/2025/May/16/openai-codex/"&gt;the confusing array of OpenAI products that share the name Codex&lt;/a&gt; a few months ago. This new model adds yet another, though at least "GPT-5-Codex" (using two hyphens) is unambiguous enough not to add to much more to the confusion.&lt;/p&gt;
&lt;p&gt;At this point it's best to think of &lt;strong&gt;Codex&lt;/strong&gt; as OpenAI's brand name for their coding family of models and tools.&lt;/p&gt;
&lt;p&gt;The new model is already integrated into their VS Code extension, the Codex CLI and their Codex Cloud asynchronous coding agent. I'd been calling that last one "Codex Web" but I think Codex Cloud is a better name since it can also be accessed directly from their iPhone app.&lt;/p&gt;
&lt;p&gt;Codex Cloud also has a new feature: you can configure it to automatically run code review against specific GitHub repositories (I found that option on &lt;a href="https://chatgpt.com/codex/settings/code-review"&gt;chatgpt.com/codex/settings/code-review&lt;/a&gt;) and it will create a temporary container to use as part of those reviews. Here's the &lt;a href="https://developers.openai.com/codex/cloud/code-review"&gt;relevant documentation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Some documented features of the new GPT-5-Codex model:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Specifically trained for code review, which directly supports their new code review feature.&lt;/li&gt;
&lt;li&gt;"GPT‑5-Codex adapts how much time it spends thinking more dynamically based on the complexity of the task." Simple tasks (like "list files in this directory") should run faster. Large, complex tasks should use run for much longer - OpenAI report Codex crunching for seven hours in some cases!&lt;/li&gt;
&lt;li&gt;Increased score on their proprietary "code refactoring evaluation" from 33.9% for GPT-5 (high) to 51.3% for GPT-5-Codex (high). It's hard to evaluate this without seeing the details of the eval but it does at least illustrate that refactoring performance is something they've focused on here.&lt;/li&gt;
&lt;li&gt;"GPT‑5-Codex also shows significant improvements in human preference evaluations when creating mobile websites" - in the past I've habitually prompted models to "make it mobile-friendly", maybe I don't need to do that any more.&lt;/li&gt;
&lt;li&gt;"We find that comments by GPT‑5-Codex are less likely to be incorrect or unimportant" - I originally misinterpreted this as referring to comments in code but it's actually about comments left on code reviews.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;a href="https://github.com/openai/codex/blob/rust-v0.36.0/codex-rs/core/gpt_5_codex_prompt.md"&gt;system prompt for GPT-5-Codex&lt;/a&gt; in Codex CLI is worth a read. It's notably shorter than the &lt;a href="https://github.com/openai/codex/blob/rust-v0.36.0/codex-rs/core/prompt.md"&gt;system prompt for other models&lt;/a&gt; - &lt;a href="https://gist.github.com/simonw/042f1428ce22ad55ac5bc9010263a4f4/revisions"&gt;here's a diff&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Here's the section of the updated system prompt that talks about comments:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Add succinct code comments that explain what is going on if code is not self-explanatory. You should not add comments like "Assigns the value to the variable", but a brief comment might be useful ahead of a complex code block that the user would otherwise have to spend time parsing out. Usage of these comments should be rare.&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Theo Browne &lt;a href="https://www.youtube.com/watch?v=j9wvCrON3XA"&gt;has a video review&lt;/a&gt; of the model and accompanying features. He was generally impressed but noted that it was surprisingly bad at using the Codex CLI search tool to navigate code. Hopefully that's something that can fix with a system prompt update.&lt;/p&gt;
&lt;p&gt;Finally, can it drew a pelican riding a bicycle? Without API access I instead got Codex Cloud to &lt;a href="https://chatgpt.com/s/cd_68c85f433cc881918acfd8a4aeda1cc4"&gt;have a go&lt;/a&gt; by prompting:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Generate an SVG of a pelican riding a bicycle, save as pelican.svg&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here's &lt;a href="https://github.com/simonw/codex-scratchpad/pull/3"&gt;the result&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img alt="it's a bit messy - the pelican is quite good and the bicycle is quite good but the pelican is stood overlapping the bicycle not riding it." src="https://static.simonwillison.net/static/2025/gpt-5-codex-pelican.jpg" /&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/code-review"&gt;code-review&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/openai"&gt;openai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-assisted-programming"&gt;ai-assisted-programming&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/pelican-riding-a-bicycle"&gt;pelican-riding-a-bicycle&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llm-release"&gt;llm-release&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/coding-agents"&gt;coding-agents&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/async-coding-agents"&gt;async-coding-agents&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/gpt-5"&gt;gpt-5&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/codex"&gt;codex&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/theo-browne"&gt;theo-browne&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/gpt-codex"&gt;gpt-codex&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/gpt"&gt;gpt&lt;/a&gt;&lt;/p&gt;



</summary><category term="code-review"/><category term="ai"/><category term="openai"/><category term="generative-ai"/><category term="llms"/><category term="ai-assisted-programming"/><category term="pelican-riding-a-bicycle"/><category term="llm-release"/><category term="coding-agents"/><category term="async-coding-agents"/><category term="gpt-5"/><category term="codex"/><category term="theo-browne"/><category term="gpt-codex"/><category term="gpt"/></entry><entry><title>Coding with LLMs in the summer of 2025 (an update)</title><link href="https://simonwillison.net/2025/Jul/21/coding-with-llms/" rel="alternate"/><published>2025-07-21T02:42:47+00:00</published><updated>2025-07-21T02:42:47+00:00</updated><id>https://simonwillison.net/2025/Jul/21/coding-with-llms/</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://antirez.com/news/154"&gt;Coding with LLMs in the summer of 2025 (an update)&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Salvatore Sanfilippo describes his current AI-assisted development workflow. He's all-in on LLMs for code review, exploratory prototyping, pair-design and writing "part of the code under your clear specifications", but warns against leaning too hard on pure vibe coding:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;But while LLMs can write part of a code base with success (under your strict supervision, see later), and produce a very sensible speedup in development (or, the ability to develop more/better in the same time used in the past — which is what I do), when left alone with nontrivial goals they tend to produce fragile code bases that are larger than needed, complex, full of local minima choices, suboptimal in many ways. Moreover they just fail completely when the task at hand is more complex than a given level.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There are plenty of useful tips in there, especially around carefully managing your context:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When your goal is to reason with an LLM about implementing or fixing some code, you need to provide extensive information to the LLM: papers, big parts of the target code base (all the code base if possible, unless this is going to make the context window so large than the LLM performances will be impaired). And a brain dump of all your understanding of what should be done.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Salvatore warns against relying too hard on tools which hide the context for you, like editors with integrated coding agents. He prefers pasting exactly what's needed into the LLM web interface - I share his preference there.&lt;/p&gt;
&lt;p&gt;His conclusions here match &lt;a href="https://simonwillison.net/2025/Mar/11/using-llms-for-code/"&gt;my experience&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You will be able to do things that are otherwise at the borders of your knowledge / expertise while learning much in the process (yes, you can learn from LLMs, as you can learn from books or colleagues: it is one of the forms of education possible, a new one). Yet, everything produced will follow your idea of code and product, and will be of high quality and will not random fail because of errors and shortcomings introduced by the LLM. You will also retain a strong understanding of all the code written and its design.&lt;/p&gt;
&lt;/blockquote&gt;

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://news.ycombinator.com/item?id=44623953"&gt;Hacker News&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/code-review"&gt;code-review&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/salvatore-sanfilippo"&gt;salvatore-sanfilippo&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-assisted-programming"&gt;ai-assisted-programming&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/vibe-coding"&gt;vibe-coding&lt;/a&gt;&lt;/p&gt;



</summary><category term="code-review"/><category term="salvatore-sanfilippo"/><category term="ai"/><category term="generative-ai"/><category term="llms"/><category term="ai-assisted-programming"/><category term="vibe-coding"/></entry><entry><title>The Perfect Commit</title><link href="https://simonwillison.net/2022/Oct/29/the-perfect-commit/" rel="alternate"/><published>2022-10-29T20:41:01+00:00</published><updated>2022-10-29T20:41:01+00:00</updated><id>https://simonwillison.net/2022/Oct/29/the-perfect-commit/</id><summary type="html">
    &lt;p&gt;For the last few years I've been trying to center my work around creating what I consider to be the &lt;em&gt;Perfect Commit&lt;/em&gt;. This is a single commit that contains all of the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;implementation&lt;/strong&gt;: a single, focused change&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tests&lt;/strong&gt; that demonstrate the implementation works&lt;/li&gt;
&lt;li&gt;Updated &lt;strong&gt;documentation&lt;/strong&gt; reflecting the change&lt;/li&gt;
&lt;li&gt;A link to an &lt;strong&gt;issue thread&lt;/strong&gt; providing further context&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Our job as software engineers generally isn't to write new software from scratch: we spend the majority of our time adding features and fixing bugs in existing software.&lt;/p&gt;
&lt;p&gt;The commit is our principle unit of work. It deserves to be treated thoughtfully and with care.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Update 26th November 2022&lt;/strong&gt;: My 25 minute talk &lt;a href="https://simonwillison.net/2022/Nov/26/productivity/"&gt;Massively increase your productivity on personal projects with comprehensive documentation and automated tests&lt;/a&gt; describes this approach to software development in detail.&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href="https://simonwillison.net/2022/Oct/29/the-perfect-commit/#implementation"&gt;Implementation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://simonwillison.net/2022/Oct/29/the-perfect-commit/#tests"&gt;Tests&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://simonwillison.net/2022/Oct/29/the-perfect-commit/#documentation"&gt;Documentation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://simonwillison.net/2022/Oct/29/the-perfect-commit/#link-to-an-issue"&gt;A link to an issue&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://simonwillison.net/2022/Oct/29/the-perfect-commit/#issue-over-commit-message"&gt;An issue is more valuable than a commit message&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://simonwillison.net/2022/Oct/29/the-perfect-commit/#not-all-perfect"&gt;Not every commit needs to be "perfect"&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://simonwillison.net/2022/Oct/29/the-perfect-commit/#scrappy-branches"&gt;Write scrappy commits in a branch&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://simonwillison.net/2022/Oct/29/the-perfect-commit/#examples"&gt;Some examples&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id="implementation"&gt;Implementation&lt;/h4&gt;
&lt;p&gt;Each commit should change a single thing.&lt;/p&gt;
&lt;p&gt;The definition of "thing" here is left deliberately vague!&lt;/p&gt;
&lt;p&gt;The goal is have something that can be easily reviewed, and that can be clearly understood in the future when revisited using tools like &lt;code&gt;git blame&lt;/code&gt; or &lt;a href="https://til.simonwillison.net/git/git-bisect"&gt;git bisect&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I like to keep my commit history linear, as I find that makes it much easier to comprehend later. This further reinforces the value of each commit being a single, focused change.&lt;/p&gt;
&lt;p&gt;Atomic commits are also much easier to cleanly revert if something goes wrong - or to cherry-pick into other branches.&lt;/p&gt;
&lt;p&gt;For things like web applications that can be deployed to production, a commit should be a unit that can be deployed. Aiming to keep the main branch in a deployable state is a good rule of thumb for deciding if a commit is a sensible atomic change or not.&lt;/p&gt;
&lt;h4 id="tests"&gt;Tests&lt;/h4&gt;
&lt;p&gt;The ultimate goal of tests is to &lt;em&gt;increase&lt;/em&gt; your productivity. If your testing practices are slowing you down, you should consider ways to improve them.&lt;/p&gt;
&lt;p&gt;In the longer term, this productivity improvement comes from gaining the freedom to make changes and stay confident that your change hasn't broken something else.&lt;/p&gt;
&lt;p&gt;But tests can help increase productivity in the immediate short term as well.&lt;/p&gt;
&lt;p&gt;How do you know when the change you have made is finished and ready to commit? It's ready when the new tests pass.&lt;/p&gt;
&lt;p&gt;I find this reduces the time I spend second-guessing myself and questioning whether I've done enough and thought through all of the edge cases.&lt;/p&gt;
&lt;p&gt;Without tests, there's a very strong possibility that your change will have broken some other, potentially unrelated feature. Your commit could be held up by hours of tedious manual testing. Or you could &lt;abbr title="You Only Live Once"&gt;YOLO&lt;/abbr&gt; it and learn that you broke something important later!&lt;/p&gt;
&lt;p&gt;Writing tests becomes far less time consuming if you already have good testing practices in place.&lt;/p&gt;
&lt;p&gt;Adding a new test to a project with a lot of existing tests is easy: you can often find an existing test that has 90% of the pattern you need already worked out for you.&lt;/p&gt;
&lt;p&gt;If your project has no tests at all, adding a test for your change will be a lot more work.&lt;/p&gt;
&lt;p&gt;This is why I start every single one of my projects with a passing test. It doesn't matter what this test is - &lt;code&gt;assert 1 + 1 == 2&lt;/code&gt; is fine! The key thing is to get a testing framework in place, such that you can run a command (for me that's usually &lt;code&gt;pytest&lt;/code&gt;) to execute the test suite - and you have an obvious place to add new tests in the future.&lt;/p&gt;
&lt;p&gt;I use &lt;a href="https://simonwillison.net/2021/Aug/28/dynamic-github-repository-templates/"&gt;these cookiecutter templates&lt;/a&gt; for almost all of my new projects. They configure a testing framework with a single passing test and GitHub Actions workflows to exercise it all from the very start.&lt;/p&gt;
&lt;p&gt;I'm not a huge advocate of test-first development, where tests are written before the code itself. What I care about is tests-included development, where the final commit bundles the tests and the implementation together. I wrote more about my approach to testing in &lt;a href="https://simonwillison.net/2020/Feb/11/cheating-at-unit-tests-pytest-black/"&gt;How to cheat at unit tests with pytest and Black&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id="documentation"&gt;Documentation&lt;/h4&gt;
&lt;p&gt;If your project defines APIs that are meant to be used outside of your project, they need to be documented. In my work these projects are usually one of the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python APIs (modules, functions and classes) that provide code designed to be imported into other projects.&lt;/li&gt;
&lt;li&gt;Web APIs - usually JSON over HTTP these days - that provide functionality to be consumed by other applications.&lt;/li&gt;
&lt;li&gt;Command line interface tools, such as those implemented using &lt;a href="https://click.palletsprojects.com/"&gt;Click&lt;/a&gt; or &lt;a href="https://typer.tiangolo.com/"&gt;Typer&lt;/a&gt; or &lt;a href="https://docs.python.org/3/library/argparse.html"&gt;argparse&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It is critical that this documentation &lt;strong&gt;must live in the same repository as the code itself&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This is important for a number of reasons.&lt;/p&gt;
&lt;p&gt;Documentation is only valuable &lt;strong&gt;if people trust it&lt;/strong&gt;. People will only trust it if they know that it is kept up to date.&lt;/p&gt;
&lt;p&gt;If your docs live in a separate wiki somewhere it's easy for them to get out of date - but more importantly it's hard for anyone to quickly confirm if the documentation is being updated in sync with the code or not.&lt;/p&gt;
&lt;p&gt;Documentation should be &lt;strong&gt;versioned&lt;/strong&gt;. People need to be able to find the docs for the specific version of your software that they are using. Keeping it in the same repository as the code gives you synchronized versioning for free.&lt;/p&gt;
&lt;p&gt;Documentation changes should be &lt;strong&gt;reviewed&lt;/strong&gt; in the same way as your code. If they live in the same repository you can catch changes that need to be reflected in the documentation as part of your code review process.&lt;/p&gt;
&lt;p&gt;And ideally, documentation should be &lt;strong&gt;tested&lt;/strong&gt;. I wrote about my approach to doing this using &lt;a href="https://simonwillison.net/2018/Jul/28/documentation-unit-tests/"&gt;Documentation unit tests&lt;/a&gt;. Executing example code in the documentation using a testing framework is a great idea too.&lt;/p&gt;
&lt;p&gt;As with tests, writing documentation from scratch is much more work than incrementally modifying existing documentation.&lt;/p&gt;
&lt;p&gt;Many of my commits include documentation that is just a sentence or two. This doesn't take very long to write, but it adds up to something very comprehensive over time.&lt;/p&gt;
&lt;p&gt;How about end-user facing documentation? I'm still figuring that out myself. I created my &lt;a href="https://simonwillison.net/2022/Mar/10/shot-scraper/"&gt;shot-scraper tool&lt;/a&gt; to help automate the process of keeping screenshots up-to-date, but I've not yet found personal habits and styles for end-user documentation that I'm confident in.&lt;/p&gt;
&lt;h4 id="link-to-an-issue"&gt;A link to an issue&lt;/h4&gt;
&lt;p&gt;Every perfect commit should include a link to an issue thread that accompanies that change.&lt;/p&gt;
&lt;p&gt;Sometimes I'll even open an issue seconds before writing the commit message, just to give myself something I can link to from the commit itself!&lt;/p&gt;
&lt;p&gt;The reason I like issue threads is that they provide effectively unlimited space for commentary and background for the change that is being made.&lt;/p&gt;
&lt;p&gt;Most of my issue threads are me talking to myself - sometimes with dozens of issue comments, all written by me.&lt;/p&gt;
&lt;p&gt;Things that can go in an issue thread include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Background&lt;/strong&gt;: the reason for the change. I try to include this in the opening comment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State of play&lt;/strong&gt; before the change. I'll often link to the current version of the code and documentation. This is great for if I return to an open issue a few days later, as it saves me from having to repeat that initial research.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Links to things&lt;/strong&gt;. So many links! Inspiration for the change, relevant documentation, conversations on Slack or Discord, clues found on StackOverflow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code snippets&lt;/strong&gt; illustrating potential designs and false-starts. Use &lt;code&gt;```python ... ```&lt;/code&gt; blocks to get syntax highlighting in your issue comments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decisions&lt;/strong&gt;. What did you consider? What did you decide? As programmers we make hundreds of tiny decisions a day. Write them down! Then you'll never find yourself relitigating them in the future having forgotten your original reasoning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Screenshots&lt;/strong&gt;. What it looked like before, what it looked like after. Animated screenshots are even better! I use &lt;a href="https://www.cockos.com/licecap/"&gt;LICEcap&lt;/a&gt; to generate quick GIF screen captures or QuickTime to capture videos - both of which can be dropped straight into a GitHub issue comment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prototypes&lt;/strong&gt;. I'll often paste a few lines of code copied from a Python console session. Sometimes I'll even paste in a block of HTML and CSS, or add a screenshot of a UI prototype.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After I've closed my issues I like to add one last comment that links to the updated documentation and ideally a live demo of the new feature.&lt;/p&gt;
&lt;h4 id="issue-over-commit-message"&gt;An issue is more valuable than a commit message&lt;/h4&gt;
&lt;p&gt;I went through a several year phase of writing essays in my commit messages, trying to capture as much of the background context and thinking as possible.&lt;/p&gt;
&lt;p&gt;My commit messages grew a lot shorter when I started bundling the updated documentation in the commit - since often much of the material I'd previously included in the commit message was now in that documentation instead.&lt;/p&gt;
&lt;p&gt;As I extended my practice of writing issue threads, I found that they were a better place for most of this context than the commit messages themselves. They supported embedded media, were more discoverable and I could continue to extend them even after the commit had landed.&lt;/p&gt;
&lt;p&gt;Today many of my commit messages are a single line summary and a link to an issue!&lt;/p&gt;
&lt;p&gt;The biggest benefit of lengthy commit messages is that they are guaranteed to survive for as long as the repository itself. If you're going to use issue threads in the way I describe here it is critical that you consider their long term archival value.&lt;/p&gt;
&lt;p&gt;I expect this to be controversial! I'm advocating for abandoning one of the core ideas of Git here - that each repository should incorporate a full, decentralized record of its history that is copied in its entirety when someone clones a repo.&lt;/p&gt;
&lt;p&gt;I understand that philosophy. All I'll say here is that my own experience has been that dropping that requirement has resulted in a net increase in my overall productivity. Other people may reach a different conclusion.&lt;/p&gt;
&lt;p&gt;If this offends you too much, you're welcome to construct an &lt;em&gt;even more perfect commit&lt;/em&gt; that incorporates background information and additional context in an extended commit message as well.&lt;/p&gt;
&lt;p&gt;One of the reasons I like GitHub Issues is that it includes a comprehensive API, which can be used to extract all of that data. I use my &lt;a href="https://github.com/dogsheep/github-to-sqlite"&gt;github-to-sqlite tool&lt;/a&gt; to maintain an ongoing archive of my issues and issue comments as a SQLite database file.&lt;/p&gt;
&lt;h4 id="not-all-perfect"&gt;Not every commit needs to be "perfect"&lt;/h4&gt;
&lt;p&gt;I find that the vast majority of my work fits into this pattern, but there are exceptions.&lt;/p&gt;
&lt;p&gt;Typo fix for some documentation or a comment? Just ship it, it's fine.&lt;/p&gt;
&lt;p&gt;Bug fix that doesn't deserve documentation? Still bundle the implementation and the test plus a link to an issue, but no need to update the docs - especially if they already describe the expected bug-free behaviour.&lt;/p&gt;
&lt;p&gt;Generally though, I find that aiming for implementation, tests, documentation and an issue link covers almost all of my work. It's a really good default model.&lt;/p&gt;
&lt;h4 id="scrappy-branches"&gt;Write scrappy commits in a branch&lt;/h4&gt;
&lt;p&gt;If I'm writing more exploratory or experimental code it often doesn't make sense to work in this strict way. For those instances I'll usually work in a branch, where I can ship "WIP" commit messages and failing tests with abandon. I'll then squash-merge them into a single perfect commit (sometimes via a self-closed GitHub pull request) to keep my main branch as tidy as possible.&lt;/p&gt;
&lt;h4 id="examples"&gt;Some examples&lt;/h4&gt;
&lt;p&gt;Here are some examples of my commits that follow this pattern:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/simonw/datasette/commit/9676b2deb07cff20247ba91dad3e84a4ab0b00d1"&gt;Upgrade Docker images to Python 3.11&lt;/a&gt; for &lt;a href="https://github.com/simonw/datasette/issues/1853"&gt;datasette #1853&lt;/a&gt; - a pretty tiny change, but still includes tests, docs and an issue link.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/simonw/sqlite-utils/commit/ab8d4aad0c42f905640981f6f24bc1e37205ae62"&gt;sqlite-utils schema now takes optional tables&lt;/a&gt; for &lt;a href="https://github.com/simonw/sqlite-utils/issues/299"&gt;sqlite-utils #299&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/simonw/shot-scraper/commit/5048e21a1ca5accedfeca6ac25a16a38dc240b81"&gt;shot-scraper html command&lt;/a&gt; for &lt;a href="https://github.com/simonw/shot-scraper/issues/96"&gt;shot-scraper #96&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/simonw/s3-credentials/commit/c7bb7268c4a124349bb511f7ec3ee3f28f9581ad"&gt;s3-credentials put-objects command&lt;/a&gt; for &lt;a href="https://github.com/simonw/s3-credentials/issues/68"&gt;s3-credentials #68&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/simonw/datasette-gunicorn/commit/0d561d7a94f76079b1eb7779b3e944c163d2539e"&gt;Initial implementation&lt;/a&gt; for &lt;a href="https://github.com/simonw/datasette-gunicorn/issues/1"&gt;datasette-gunicorn #1&lt;/a&gt; - this was the first commit to this repository, but I still bundled the tests, docs, implementation and a link to an issue.&lt;/li&gt;
&lt;/ul&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/code-review"&gt;code-review&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/definitions"&gt;definitions&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/documentation"&gt;documentation&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/git"&gt;git&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/github"&gt;github&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/software-engineering"&gt;software-engineering&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/testing"&gt;testing&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/github-issues"&gt;github-issues&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="code-review"/><category term="definitions"/><category term="documentation"/><category term="git"/><category term="github"/><category term="software-engineering"/><category term="testing"/><category term="github-issues"/></entry><entry><title>Quoting Google Standard of Code Review</title><link href="https://simonwillison.net/2019/Nov/28/google-standard-code-review/" rel="alternate"/><published>2019-11-28T05:40:10+00:00</published><updated>2019-11-28T05:40:10+00:00</updated><id>https://simonwillison.net/2019/Nov/28/google-standard-code-review/</id><summary type="html">
    &lt;blockquote cite="https://google.github.io/eng-practices/review/reviewer/standard.html"&gt;&lt;p&gt;In general, reviewers should favor approving a CL [code review] once it is in a state where it definitely improves the overall code health of the system being worked on, even if the CL isn’t perfect.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="cite"&gt;&amp;mdash; &lt;a href="https://google.github.io/eng-practices/review/reviewer/standard.html"&gt;Google Standard of Code Review&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/code-review"&gt;code-review&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/google"&gt;google&lt;/a&gt;&lt;/p&gt;



</summary><category term="code-review"/><category term="google"/></entry><entry><title>Quoting Charity Majors</title><link href="https://simonwillison.net/2018/Aug/27/charity-majors/" rel="alternate"/><published>2018-08-27T21:00:46+00:00</published><updated>2018-08-27T21:00:46+00:00</updated><id>https://simonwillison.net/2018/Aug/27/charity-majors/</id><summary type="html">
    &lt;blockquote cite="https://charity.wtf/2018/08/19/shipping-software-should-not-be-scary/amp/?__twitter_impression=true"&gt;&lt;p&gt;In too many organizations, deploy code is a technical backwater, an accumulation of crufty scripts and glue code, forked gems and interns’ earnest attempts to hack up Capistrano.  It usually gives off a strong whiff of “sloppily evolved from many 2 am patches with no code review”.&lt;/p&gt;
&lt;p&gt;This is insane.  Deploy software is the most important software you have.  Treat it that way: recruit an owner, allocate real time for development and testing, bake in metrics and track them over time.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="cite"&gt;&amp;mdash; &lt;a href="https://charity.wtf/2018/08/19/shipping-software-should-not-be-scary/amp/?__twitter_impression=true"&gt;Charity Majors&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/code-review"&gt;code-review&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/deployment"&gt;deployment&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/charity-majors"&gt;charity-majors&lt;/a&gt;&lt;/p&gt;



</summary><category term="code-review"/><category term="deployment"/><category term="charity-majors"/></entry><entry><title>How to Do Code Reviews Like a Human</title><link href="https://simonwillison.net/2017/Oct/13/code-reviews/" rel="alternate"/><published>2017-10-13T04:36:39+00:00</published><updated>2017-10-13T04:36:39+00:00</updated><id>https://simonwillison.net/2017/Oct/13/code-reviews/</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://mtlynch.io/human-code-reviews-1/"&gt;How to Do Code Reviews Like a Human&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Some very well thought out advice on giving constructive reviews, including simple but effective language tricks for keeping suggestions positive and helpful.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/code-review"&gt;code-review&lt;/a&gt;&lt;/p&gt;



</summary><category term="code-review"/></entry><entry><title>What is a good onboarding process for a new employee at a startup?</title><link href="https://simonwillison.net/2013/Aug/13/what-is-a-good/" rel="alternate"/><published>2013-08-13T12:51:00+00:00</published><updated>2013-08-13T12:51:00+00:00</updated><id>https://simonwillison.net/2013/Aug/13/what-is-a-good/</id><summary type="html">
    &lt;p&gt;&lt;em&gt;My answer to &lt;a href="https://www.quora.com/What-is-a-good-onboarding-process-for-a-new-employee-at-a-startup/answer/Simon-Willison"&gt;What is a good onboarding process for a new employee at a startup?&lt;/a&gt; on Quora&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Have them deploy the site on their first day. This ensures they know how to...&lt;/p&gt;

&lt;ol&gt;&lt;li&gt;Set up a working development environment&lt;/li&gt;&lt;li&gt;Check code out of your repository&lt;/li&gt;&lt;li&gt;Navigate the code base&lt;/li&gt;&lt;li&gt;Make code changes&lt;/li&gt;&lt;li&gt;Run tests&lt;/li&gt;&lt;li&gt;Pass a code review (or at least get some peer review)&lt;/li&gt;&lt;li&gt;QA their change beyond just the automated tests&lt;/li&gt;&lt;li&gt;Deploy their change to production&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;If they do all of this on day one, they'll come in on day two ready to start building and shipping production code.

&lt;p&gt;This also means your team need to have a development/deployment environment that can be set up in less than a day, albeit with a little guidance. This is a very good thing.&lt;/p&gt;

&lt;p&gt;If your infrastructure is good enough you can even do this with non-technical employees as well - let them edit the "about" page on your site to add themselves through the GitHub web editor and hit a "deploy" button in Jenkins or similar to deploy the site!&lt;/p&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/code-review"&gt;code-review&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/startups"&gt;startups&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/quora"&gt;quora&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/hr"&gt;hr&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="code-review"/><category term="startups"/><category term="quora"/><category term="hr"/></entry><entry><title>What are the best practices for onboarding new software engineers?</title><link href="https://simonwillison.net/2012/Nov/14/what-are-the-best/" rel="alternate"/><published>2012-11-14T15:17:00+00:00</published><updated>2012-11-14T15:17:00+00:00</updated><id>https://simonwillison.net/2012/Nov/14/what-are-the-best/</id><summary type="html">
    &lt;p&gt;&lt;em&gt;My answer to &lt;a href="https://www.quora.com/What-are-the-best-practices-for-onboarding-new-software-engineers/answer/Simon-Willison"&gt;What are the best practices for onboarding new software engineers?&lt;/a&gt; on Quora&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I'm a huge fan of "deploy on the first day" - which forces the issue in getting all of their accounts set up, their development environment ready, showing them where source control is, how code review works and so on. Even if it's just adding themselves to the about page or humans.txt file, it means they can come in on day two ready to get real work done.&lt;/p&gt;

&lt;p&gt;I can't say how well that would scale up to Twitter/Facebook, but for a small startup like ours it works extremely well.&lt;/p&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/code-review"&gt;code-review&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/programmers"&gt;programmers&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/software-engineering"&gt;software-engineering&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/startups"&gt;startups&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/quora"&gt;quora&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="code-review"/><category term="programmers"/><category term="software-engineering"/><category term="startups"/><category term="quora"/></entry><entry><title>Design and code review requested for Django string signing / signed cookies</title><link href="https://simonwillison.net/2010/Jan/4/codereview/" rel="alternate"/><published>2010-01-04T13:24:50+00:00</published><updated>2010-01-04T13:24:50+00:00</updated><id>https://simonwillison.net/2010/Jan/4/codereview/</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://groups.google.com/group/django-developers/browse_thread/thread/297e8b22006f7f3a"&gt;Design and code review requested for Django string signing / signed cookies&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Do you know your way around web app security and cryptography (in particular signing things using hmac and sha1)? We’d appreciate your help reviewing the usage of these concepts in Django’s proposed string signing and signed cookie implementations.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/code-review"&gt;code-review&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/cryptography"&gt;cryptography&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/django"&gt;django&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/hashing"&gt;hashing&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/hmac"&gt;hmac&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/security"&gt;security&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/sha1"&gt;sha1&lt;/a&gt;&lt;/p&gt;



</summary><category term="code-review"/><category term="cryptography"/><category term="django"/><category term="hashing"/><category term="hmac"/><category term="python"/><category term="security"/><category term="sha1"/></entry><entry><title>How to use Google Code's code review tool</title><link href="https://simonwillison.net/2008/Aug/28/codereviews/" rel="alternate"/><published>2008-08-28T16:25:38+00:00</published><updated>2008-08-28T16:25:38+00:00</updated><id>https://simonwillison.net/2008/Aug/28/codereviews/</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://code.google.com/p/support/wiki/CodeReviews"&gt;How to use Google Code&amp;#x27;s code review tool&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
I missed this, but Google Code now has a pleasantly simple code review system built in to the source code browser. You can add comments to any changeset, including annotations attached to individual lines of code.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/code-review"&gt;code-review&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/google-code"&gt;google-code&lt;/a&gt;&lt;/p&gt;



</summary><category term="code-review"/><category term="google-code"/></entry><entry><title>Review Board</title><link href="https://simonwillison.net/2007/May/31/chiplog/" rel="alternate"/><published>2007-05-31T08:32:44+00:00</published><updated>2007-05-31T08:32:44+00:00</updated><id>https://simonwillison.net/2007/May/31/chiplog/</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.chipx86.com/blog/?p=222"&gt;Review Board&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
VMWare release a slick looking Django-powered code review system, with hooks in to Subversion and Perforce.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/code-review"&gt;code-review&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/django"&gt;django&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/perforce"&gt;perforce&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/subversion"&gt;subversion&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/vmware"&gt;vmware&lt;/a&gt;&lt;/p&gt;



</summary><category term="code-review"/><category term="django"/><category term="perforce"/><category term="subversion"/><category term="vmware"/></entry></feed>