{
    "componentChunkName": "component---src-templates-blog-post-js",
    "path": "/my-ai-writes-the-commit-message-first-then-i-write-the-code/",
    "result": {"data":{"site":{"siteMetadata":{"title":"catch { snail }","author":"Andrew"}},"markdownRemark":{"id":"82cf150e-2760-58f8-9110-78536c0e854c","excerpt":"Quarantine lasted long enough. Here’s the promised post about the  hook — except the project mutated into something much weirder along the way. The plan Simple…","html":"<p>Quarantine lasted long enough. Here’s the <a href=\"/gpt2-commit-messages\">promised</a> post about the <code class=\"language-text\">prepare-commit-msg</code> hook — except the project mutated into something much weirder along the way.</p>\n<h2 id=\"the-plan\" style=\"position:relative;\"><a href=\"#the-plan\" aria-label=\"the plan permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The plan</h2>\n<p>Simple: a git hook grabs the staged diff, sends it to my fine-tuned GPT-2 from last month, and the model suggests a commit message. Since loading a 500MB model on every commit is insane, the model lives in a tiny Flask server that stays warm:</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">from</span> flask <span class=\"token keyword\">import</span> Flask<span class=\"token punctuation\">,</span> request\n\napp <span class=\"token operator\">=</span> Flask<span class=\"token punctuation\">(</span>__name__<span class=\"token punctuation\">)</span>\ngenerator <span class=\"token operator\">=</span> load_my_finetuned_gpt2<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>  <span class=\"token comment\"># from last post</span>\n\n<span class=\"token decorator annotation punctuation\">@app<span class=\"token punctuation\">.</span>route</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"/suggest\"</span><span class=\"token punctuation\">,</span> methods<span class=\"token operator\">=</span><span class=\"token punctuation\">[</span><span class=\"token string\">\"POST\"</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">def</span> <span class=\"token function\">suggest</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    diff <span class=\"token operator\">=</span> request<span class=\"token punctuation\">.</span>form<span class=\"token punctuation\">[</span><span class=\"token string\">\"diff\"</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">[</span><span class=\"token punctuation\">:</span><span class=\"token number\">3000</span><span class=\"token punctuation\">]</span>\n    <span class=\"token keyword\">return</span> generator<span class=\"token punctuation\">(</span>diff<span class=\"token punctuation\">)</span></code></pre></div>\n<p>And the hook:</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\"><span class=\"token shebang important\">#!/bin/sh</span>\n<span class=\"token comment\"># .git/hooks/prepare-commit-msg</span>\n<span class=\"token assign-left variable\">DIFF</span><span class=\"token operator\">=</span><span class=\"token variable\"><span class=\"token variable\">$(</span><span class=\"token function\">git</span> <span class=\"token function\">diff</span> --cached<span class=\"token variable\">)</span></span>\n<span class=\"token assign-left variable\">MSG</span><span class=\"token operator\">=</span><span class=\"token variable\"><span class=\"token variable\">$(</span><span class=\"token function\">curl</span> -s localhost:5000/suggest --data-urlencode <span class=\"token string\">\"diff=<span class=\"token variable\">$DIFF</span>\"</span><span class=\"token variable\">)</span></span>\n<span class=\"token builtin class-name\">printf</span> <span class=\"token string\">'# suggested: %s\\n%s'</span> <span class=\"token string\">\"<span class=\"token variable\">$MSG</span>\"</span> <span class=\"token string\">\"<span class=\"token variable\"><span class=\"token variable\">$(</span><span class=\"token function\">cat</span> <span class=\"token string\">\"<span class=\"token variable\">$1</span>\"</span><span class=\"token variable\">)</span></span>\"</span> <span class=\"token operator\">></span> <span class=\"token string\">\"<span class=\"token variable\">$1</span>\"</span></code></pre></div>\n<h2 id=\"the-failure-as-promised\" style=\"position:relative;\"><a href=\"#the-failure-as-promised\" aria-label=\"the failure as promised permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The failure (as promised)</h2>\n<p>It was wrong 100% of the time, but the <em>reasons</em> are more interesting than the result:</p>\n<p><strong>The model has never seen a diff.</strong> I fine-tuned it on commit messages only. From its point of view, a diff is line noise, so it responds to <code class=\"language-text\">+import redis</code> with “fix typo in readme”. Training distribution is everything — a lesson people apparently keep having to relearn at every scale.</p>\n<p><strong>1024 tokens.</strong> GPT-2’s entire context window. My average staged diff is 3–4x that. The model was writing commit messages after reading the first file’s worth of changes, which, to be fair, is also how some humans review PRs.</p>\n<p><strong>It completes, it doesn’t obey.</strong> This is the big one. GPT-2 is an autocomplete engine. There’s no way to <em>tell</em> it “summarize this diff” — you can only arrange text and hope the most probable continuation happens to be what you wanted. What these models are missing isn’t size, it’s some way of being trained to follow intent. Until someone figures that out, everything built on them is prompt origami.</p>\n<h2 id=\"the-inversion\" style=\"position:relative;\"><a href=\"#the-inversion\" aria-label=\"the inversion permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>The inversion</h2>\n<p>Staring at another wrong suggestion, it hit me: the model can’t describe what I <em>did</em>, but it’s weirdly good at proposing things I <em>could do</em>. It’s been trained on 3,000 of my past intentions.</p>\n<p>So I flipped the workflow. Every morning the model deals me a commit message. Then I have to write code that makes the message true.</p>\n<p>Week one assignments, verbatim:</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">delete old feature flags\nfix flaky test\nadd caching to search\nupdate deps and pray</code></pre></div>\n<p>Here’s the unsettling part: <strong>all four were real work I’d been avoiding.</strong> I found three dead feature flags, one genuinely flaky test, and a search endpoint that absolutely needed caching. The model isn’t psychic — it’s a compressed statistical summary of my habits, and my habits include perpetually deferring the same maintenance. It’s like Brian Eno’s Oblique Strategies, except the deck was generated from my own guilt.</p>\n<h2 id=\"what-this-actually-is\" style=\"position:relative;\"><a href=\"#what-this-actually-is\" aria-label=\"what this actually is permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>What this actually is</h2>\n<p>The hook was supposed to automate me out of a chore. What I got instead is a slot machine that pays out in chores — and it works <em>because</em> it’s random-but-in-my-distribution. A model too weak to answer questions can still be a fantastic question generator.</p>","frontmatter":{"title":"My AI writes the commit message first. Then I write the code","date":"April 25, 2020","description":"The GPT-2 commit hook failed exactly as promised, so I turned it around"}}},"pageContext":{"slug":"/my-ai-writes-the-commit-message-first-then-i-write-the-code/","previous":{"fields":{"slug":"/i-fine-tuned-gpt-2-on-my-commit-messages-im-sorry/"},"frontmatter":{"title":"I fine-tuned GPT-2 on my commit messages (I'm sorry)"}},"next":{"fields":{"slug":"/gpt-3-my-fine-tuning-posts-might-already-be-obsolete/"},"frontmatter":{"title":"GPT-3: my fine-tuning posts might already be obsolete"}}}},
    "staticQueryHashes": ["3435731857","426816048","63159454"]}