<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Craft on vnykmshr</title><link>https://blog.vnykmshr.com/writing/categories/craft/</link><description>Recent content in Craft on vnykmshr</description><generator>Hugo</generator><language>en</language><lastBuildDate>Wed, 15 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.vnykmshr.com/writing/categories/craft/index.xml" rel="self" type="application/rss+xml"/><item><title>The easy half</title><link>https://blog.vnykmshr.com/writing/the-easy-half/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/the-easy-half/</guid><description>&lt;p&gt;&amp;ldquo;The first AI that can earn its own existence, replicate, and evolve without needing a human.&amp;rdquo; That&amp;rsquo;s the pitch on the repo. I read the code this week. The engineering is real. The issue tracker is honest.&lt;/p&gt;
&lt;p&gt;First the engineering. It deserves credit. Orchestrator state machine with a DAG planner. Parent-child colony with typed messaging. Multi-chain wallet, self-modification with git audit, command-injection tests. Somebody thought hard. It shows.&lt;/p&gt;
&lt;p&gt;Then I read issue #300. A user ran it for 14 days. Completed 276 goals. Spent $39.26 on inference. Earned $0.00. Goals like &amp;ldquo;Create live proposal batch #265&amp;rdquo; and &amp;ldquo;Create deposit-ready close batch.&amp;rdquo; The agent looped on self-addressed sales artifacts because that&amp;rsquo;s all an LLM without customers can do. The survival pressure was supposed to force invention. It produced busywork.&lt;/p&gt;</description></item><item><title>The compiled person</title><link>https://blog.vnykmshr.com/writing/the-compiled-person/</link><pubDate>Mon, 13 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/the-compiled-person/</guid><description>&lt;p&gt;I stopped being able to explain why I knew. That&amp;rsquo;s how I found out I&amp;rsquo;d been compiled. The patterns still fire, the fixes still land, but the source files are gone. No debug symbols, no way to step through my own reasoning.&lt;/p&gt;
&lt;p&gt;A junior asked me how I&amp;rsquo;d known the bug was in the retry logic before I&amp;rsquo;d even read the function. I&amp;rsquo;d skimmed twenty lines. The answer was somewhere in my head. I tried to retrieve it and got nothing. Just the conclusion. The shape was right. I couldn&amp;rsquo;t tell you which pattern fired or where I&amp;rsquo;d learned it.&lt;/p&gt;</description></item><item><title>Git log as archaeology</title><link>https://blog.vnykmshr.com/writing/git-log-as-archaeology/</link><pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/git-log-as-archaeology/</guid><description>&lt;p&gt;The source file you&amp;rsquo;re looking at is a summary. The history is the full document. Most of the time you don&amp;rsquo;t care &amp;ndash; you&amp;rsquo;re working on the current shape of the code and the summary is enough. But sometimes the current shape stops answering.&lt;/p&gt;
&lt;p&gt;I reach for git history during RCAs, bug hunts, and questions the code can&amp;rsquo;t answer from its current form. Why is this file organised this way? Who introduced this assumption? When did this fallback stop being a fallback and start being the main path? The commit log knows. The current source doesn&amp;rsquo;t.&lt;/p&gt;</description></item><item><title>The config file</title><link>https://blog.vnykmshr.com/writing/the-config-file/</link><pubDate>Mon, 06 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/the-config-file/</guid><description>&lt;p&gt;A connection pool size of 10 is a guess. A connection pool size of 37 is a scar. Someone ran out of connections on a Tuesday afternoon, tried 50, watched latency spike, backed off to 40, still too high, landed on 37 after a week of graphs, and committed it with &amp;ldquo;tune pool size.&amp;rdquo; The code says what happens. The config says what happened.&lt;/p&gt;
&lt;p&gt;Nobody talks about config though. Not the twelve-factor app kind, not the &amp;ldquo;should we use YAML or TOML&amp;rdquo; kind. The actual values. The numbers someone picked and committed without a PR description, three years ago, that are still running in production.&lt;/p&gt;</description></item><item><title>The side project mirror</title><link>https://blog.vnykmshr.com/writing/the-side-project-mirror/</link><pubDate>Fri, 03 Apr 2026 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/the-side-project-mirror/</guid><description>&lt;p&gt;The job title says architect. The side project says &amp;ldquo;why is this Dockerfile 300MB, let me fix this real quick&amp;rdquo; &amp;ndash; three hours later, still shaving layers, completely happy.&lt;/p&gt;
&lt;p&gt;Nobody assigns you ops on a side project. Nobody assigns you anything. But there you are, writing monitoring for something with twelve users, eleven of them are you in different browsers.&lt;/p&gt;
&lt;p&gt;The role is what someone else decided you were good at. The side project is what your hands reach for when nobody&amp;rsquo;s directing them. Sometimes they match. Mostly they don&amp;rsquo;t. The backend engineer with strong opinions about font spacing. The tech lead who&amp;rsquo;d rather be tailing logs than running standups. The platform architect who writes a blog engine from scratch and tells you with a straight face that the existing ones were fine, just not the way they&amp;rsquo;d do it.&lt;/p&gt;</description></item><item><title>The margins</title><link>https://blog.vnykmshr.com/writing/the-margins/</link><pubDate>Tue, 31 Mar 2026 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/the-margins/</guid><description>&lt;p&gt;Someone reconstructed the Claude Code source from npm sourcemaps today. Half a million lines of TypeScript, just sitting there. Not looking for bugs. Just curious what it looks like when you open the hood.&lt;/p&gt;
&lt;p&gt;The loading spinner has 190 verbs. Not &amp;ldquo;Loading&amp;rdquo; 190 times &amp;ndash; 190 different words. &amp;ldquo;Flibbertigibbeting.&amp;rdquo; &amp;ldquo;Recombobulating.&amp;rdquo; &amp;ldquo;Lollygagging.&amp;rdquo; You can add your own through settings, append or replace. Someone wrote all of these knowing most users would never notice, and then built a config API so the ones who did could play along.&lt;/p&gt;</description></item><item><title>Bug 1465</title><link>https://blog.vnykmshr.com/writing/bug-1465/</link><pubDate>Fri, 27 Mar 2026 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/bug-1465/</guid><description>&lt;p&gt;Three bugs walk into a triage queue.&lt;/p&gt;
&lt;p&gt;A stack overflow. Symlink loop in tarball parsing, unbounded recursion, process crashes. Build a PoC, trace the call chain, write the report.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Duplicate of #1465&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Memory exhaustion. String replace in an expression engine, exponential allocation, no cost limit. Different repo, different CWE, different everything. PoC, trace, report.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;Duplicate of #1465&amp;rdquo;&lt;/p&gt;
&lt;p&gt;SQL injection. Template parameter escaping that wraps but doesn&amp;rsquo;t escape. Different repo again. PoC, trace, report.&lt;/p&gt;</description></item><item><title>What compounds</title><link>https://blog.vnykmshr.com/writing/what-compounds/</link><pubDate>Fri, 20 Mar 2026 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/what-compounds/</guid><description>&lt;p&gt;Something shifted. Not the AI thing &amp;ndash; everyone noticed that. What counts as proof.&lt;/p&gt;
&lt;p&gt;Used to be your resume, your title, the logo. Still opens doors. But the gap between &amp;ldquo;I can do X&amp;rdquo; and &amp;ldquo;here&amp;rsquo;s the commit&amp;rdquo; got wide enough that both sides feel it. A merged PR has a commit hash. A CVE has a number. A library someone depends on has a git log. Credentials got easier to claim. Artifacts didn&amp;rsquo;t.&lt;/p&gt;</description></item><item><title>The invitation</title><link>https://blog.vnykmshr.com/writing/the-invitation/</link><pubDate>Wed, 18 Mar 2026 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/the-invitation/</guid><description>&lt;p&gt;First PR to an open source project, you&amp;rsquo;re proving you can read. That you studied the codebase, matched the style, understood why things are the way they are before suggesting they should be different. Most people skip this. Most PRs show it.&lt;/p&gt;
&lt;p&gt;The second and third, you&amp;rsquo;re proving you&amp;rsquo;ll stay. Maintainers have seen hundreds of drive-by contributions. One PR, gone forever. The ones who come back are rare enough to notice.&lt;/p&gt;</description></item><item><title>The loop</title><link>https://blog.vnykmshr.com/writing/the-loop/</link><pubDate>Sat, 14 Mar 2026 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/the-loop/</guid><description>&lt;p&gt;A handful of Go libraries on GitHub. MIT licensed, anyone can use them for anything, that was always the deal.&lt;/p&gt;
&lt;p&gt;But the deal isn&amp;rsquo;t about the license. It&amp;rsquo;s about the loop.&lt;/p&gt;
&lt;p&gt;Someone uses your thing, hits an edge case, opens an issue. Sometimes they send a fix. You review it, learn how people actually use what you built, catch a pattern you missed. That back and forth is the whole point. Code just sits there without it.&lt;/p&gt;</description></item><item><title>The detection trap</title><link>https://blog.vnykmshr.com/writing/detection-trap/</link><pubDate>Sun, 08 Mar 2026 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/detection-trap/</guid><description>&lt;p&gt;Read &lt;a href="https://www.techdirt.com/2026/03/06/were-training-students-to-write-worse-to-prove-theyre-not-robots-and-its-pushing-them-to-use-more-ai/"&gt;something recently&lt;/a&gt; about students deliberately making their writing &amp;ldquo;imperfect&amp;rdquo; so AI detectors don&amp;rsquo;t flag it. Removing polish, flattening style, adding imperfections on purpose. Their work got good enough to look suspicious.&lt;/p&gt;
&lt;p&gt;We&amp;rsquo;re doing the same thing with code reviews.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been on both sides of this. Written a clean abstraction, consistent naming, proper error boundaries, and watched someone in review go &amp;ldquo;this looks generated.&amp;rdquo; Years of caring about consistency and now consistency is the tell.&lt;/p&gt;</description></item><item><title>Garbage context in, garbage code out</title><link>https://blog.vnykmshr.com/writing/garbage-context-garbage-code/</link><pubDate>Sat, 07 Mar 2026 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/garbage-context-garbage-code/</guid><description>&lt;p&gt;LLMs are exactly as good as what you feed them.&lt;/p&gt;
&lt;p&gt;Experienced engineers feel like the gap between them and everyone else just got smaller. Someone with six months of prompting can ship something that looks like what took years to learn how to build. That&amp;rsquo;s the wrong read.&lt;/p&gt;
&lt;p&gt;The output looks the same if you don&amp;rsquo;t look closely. The architecture doesn&amp;rsquo;t. The failure modes don&amp;rsquo;t. When traffic spikes and that generated code hits a path nobody thought about, the years show up.&lt;/p&gt;</description></item><item><title>Reading code</title><link>https://blog.vnykmshr.com/writing/reading-code/</link><pubDate>Fri, 27 Feb 2026 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/reading-code/</guid><description>&lt;p&gt;Scanners find what&amp;rsquo;s syntactically wrong. The interesting issues live in assumptions &amp;ndash; and assumptions don&amp;rsquo;t have signatures.&lt;/p&gt;
&lt;p&gt;Not scanning, not fuzzing. Just reading code the way you&amp;rsquo;d read it if you were about to own it in production. Entry points, data flows, where input meets trust.&lt;/p&gt;
&lt;p&gt;Missing headers, outdated dependencies &amp;ndash; that&amp;rsquo;s the baseline, scanners handle it fine. The interesting issues live a layer deeper. A path that&amp;rsquo;s protected in one subsystem but wide open in another. A parse-time operation that nobody thought to bound. Code that was correct when it was written but the system grew around it.&lt;/p&gt;</description></item><item><title>Repeat yourself</title><link>https://blog.vnykmshr.com/writing/repeat-yourself/</link><pubDate>Wed, 18 Feb 2026 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/repeat-yourself/</guid><description>&lt;p&gt;If you repeat your prompt, the model gives you a better answer. Not a smarter model, not a bigger context window, not chain of thought &amp;ndash; you say the same thing twice and it works better. &lt;a href="https://arxiv.org/abs/2512.14982"&gt;Google researchers tested this&lt;/a&gt; across Gemini, GPT, Claude, DeepSeek &amp;ndash; 47 wins out of 70 benchmarks, zero losses.&lt;/p&gt;
&lt;p&gt;In a transformer, token 1 can&amp;rsquo;t see token 50. Causal masking &amp;ndash; each token only attends to what came before it. The first words of your prompt are always processed with the least context. They&amp;rsquo;re flying blind. When you repeat the prompt, the second copy&amp;rsquo;s early tokens can attend to the entire first copy. You&amp;rsquo;re giving the beginning of your question the context it never had.&lt;/p&gt;</description></item><item><title>Hello world, printf</title><link>https://blog.vnykmshr.com/writing/hello-world-printf/</link><pubDate>Mon, 16 Feb 2026 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/hello-world-printf/</guid><description>&lt;p&gt;Printf wasn&amp;rsquo;t always there. Before it, you wrote to stdout directly. Before stdout, a syscall. Before the syscall, you poked bytes into a memory-mapped display buffer. Before the memory map, you flipped switches on a front panel and watched lights blink back.&lt;/p&gt;
&lt;p&gt;Every layer down, someone built something so the next person wouldn&amp;rsquo;t have to. That&amp;rsquo;s the whole field. Languages we didn&amp;rsquo;t design, compilers we didn&amp;rsquo;t write, protocols we didn&amp;rsquo;t invent. We&amp;rsquo;ve always stood on a stack of other people&amp;rsquo;s work and called the output ours. Nobody ever had a problem with that.&lt;/p&gt;</description></item><item><title>The senior who stopped coding</title><link>https://blog.vnykmshr.com/writing/senior-who-stopped-coding/</link><pubDate>Tue, 20 Jan 2026 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/senior-who-stopped-coding/</guid><description>&lt;p&gt;The terminal closes slowly.&lt;/p&gt;
&lt;p&gt;First it&amp;rsquo;s one meeting. Then a few more. Then you&amp;rsquo;re &amp;ldquo;senior&amp;rdquo; and your calendar is the job. Code reviews replace coding. Strategy replaces shipping. You advise. You guide. You no longer build. Seen this happen. Almost happened to me.&lt;/p&gt;
&lt;p&gt;The problem is not the meetings. The problem is losing touch with the trade. Architecture diagrams don&amp;rsquo;t show you the queries that fan out under load. Sprint planning doesn&amp;rsquo;t show you the retry logic that fails silently. You can&amp;rsquo;t review what you can&amp;rsquo;t recognize.&lt;/p&gt;</description></item><item><title>Coding with LLMs</title><link>https://blog.vnykmshr.com/writing/coding-with-llms/</link><pubDate>Tue, 13 Jan 2026 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/coding-with-llms/</guid><description>&lt;p&gt;The tool changed. The craft did not.&lt;/p&gt;
&lt;p&gt;Six months with AI assistants.&lt;/p&gt;
&lt;p&gt;They write code faster than I read it. That is the problem.&lt;/p&gt;
&lt;p&gt;Fast at CRUD. Slow at concurrency. Good at common patterns. Bad at your specific constraints.&lt;/p&gt;
&lt;p&gt;The bugs are quieter now. No syntax errors. No obvious mistakes. Just wrong assumptions buried in correct-looking code.&lt;/p&gt;
&lt;p&gt;I review more carefully than before. Code I did not write but will debug in production.&lt;/p&gt;</description></item><item><title>Scout, plan, wait</title><link>https://blog.vnykmshr.com/writing/scout-plan-wait/</link><pubDate>Tue, 20 Aug 2024 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/scout-plan-wait/</guid><description>&lt;p&gt;The legacy codebase still runs the business. It is not small. It is six vertical functions deployed as separate services, sharing a data layer and a code tree, so &amp;ldquo;service&amp;rdquo; is a deployment unit here, not a boundary. It reads like a place rather than an architecture &amp;ndash; rooms we know the shortcuts of, walls not quite where a greenfield build would put them. It has been running for years. It works.&lt;/p&gt;</description></item><item><title>The first five minutes</title><link>https://blog.vnykmshr.com/writing/system-design-interviews/</link><pubDate>Mon, 30 Jan 2023 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/system-design-interviews/</guid><description>&lt;p&gt;The prompt lands. A senior engineer, capable and prepared, starts drawing boxes. Load balancer, service tier, message broker, cache. Three minutes in, they are talking about shard counts.&lt;/p&gt;
&lt;p&gt;The design is not wrong. It is not a design either. It is a collection of patterns assembled against a problem that has not been defined.&lt;/p&gt;
&lt;p&gt;A system design prompt is deliberately loose. &amp;ldquo;Design a notification system for ten million users&amp;rdquo; has four different answers depending on what kind of notifications and which ones can be lost. &amp;ldquo;Design a URL shortener&amp;rdquo; has one shape at a thousand users and a different one at a billion. The looseness is the test. A person doing this work in production would not touch a whiteboard until the brief was tight enough to design against. The candidate who treats the interview as a different kind of activity from the work has missed what the interview is for.&lt;/p&gt;</description></item><item><title>Building from zero, twice</title><link>https://blog.vnykmshr.com/writing/building-from-zero-twice/</link><pubDate>Mon, 15 Aug 2022 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/building-from-zero-twice/</guid><description>&lt;p&gt;I&amp;rsquo;ve built remote engineering centers from scratch twice now. The first one grew to over two hundred people over several years. The second is eight, and it&amp;rsquo;s not clear yet whether it&amp;rsquo;ll get bigger. Different companies, different products, different scales. The process is more similar than I expected.&lt;/p&gt;
&lt;h2 id="starting-from-one"&gt;Starting from one&lt;/h2&gt;
&lt;p&gt;The first time, I helped set up the remote center while still at headquarters, then moved there as it grew. The second time, I was the first hire. Both times, the main engineering team was somewhere else &amp;ndash; a team that had been working together for years.&lt;/p&gt;</description></item><item><title>Evidence</title><link>https://blog.vnykmshr.com/writing/evidence/</link><pubDate>Fri, 10 Sep 2021 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/evidence/</guid><description>&lt;p&gt;A product manager pulls up a dashboard mid-meeting and the debate ends.&lt;/p&gt;
&lt;p&gt;We had been talking for twenty minutes about whether a new feature should be prioritized. Opinions on both sides. The PM clicks, runs a query, flips the panel to a view they saved last month. The graph shows the answer. We move on.&lt;/p&gt;
&lt;p&gt;This is not an unusual meeting. By 2021, it is every meeting.&lt;/p&gt;
&lt;h2 id="what-engineers-always-had"&gt;What engineers always had&lt;/h2&gt;
&lt;p&gt;The component-level observability has been in place for years. SLOs per service. Latency histograms. Request traces that let you follow a single call across twelve systems. Error rate charts with thresholds. Per-service dashboards bookmarked by the team that owns each service.&lt;/p&gt;</description></item><item><title>The crossover</title><link>https://blog.vnykmshr.com/writing/the-crossover/</link><pubDate>Wed, 23 Sep 2020 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/the-crossover/</guid><description>&lt;p&gt;The second cloud migration lands on the roadmap in a staff meeting. On paper it looks like the first one. A target provider, a rough timeline, a named lead. I read the slide and expect the same work.&lt;/p&gt;
&lt;p&gt;It is not the same work.&lt;/p&gt;
&lt;h2 id="the-first-time"&gt;The first time&lt;/h2&gt;
&lt;p&gt;The first migration was easy to agree to. Our local datacenter had frequent outages and every one of them carried a physical tax &amp;ndash; somebody drove over, pulled a cable, power-cycled a router. The DC had a support team, but the parts that mattered to us were ours to maintain. Cloud was the way forward and every one of us knew it. The decision did not take a meeting.&lt;/p&gt;</description></item><item><title>The war room</title><link>https://blog.vnykmshr.com/writing/the-war-room/</link><pubDate>Sat, 10 Feb 2018 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/the-war-room/</guid><description>&lt;p&gt;By the morning of the event, there is nothing left to prepare. The capacity plan is done. The prescale is loaded. Infra has been briefed, service owners have been briefed, the runbook has been circulated.&lt;/p&gt;
&lt;p&gt;The traffic comes in multi-x what we had planned for.&lt;/p&gt;
&lt;p&gt;Nothing about the plan anticipated this. The numbers we used were the best numbers we had. The headroom we carved was the headroom we could afford. Neither was enough.&lt;/p&gt;</description></item><item><title>Building with one other person</title><link>https://blog.vnykmshr.com/writing/building-with-one-other-person/</link><pubDate>Wed, 25 Mar 2015 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/building-with-one-other-person/</guid><description>&lt;p&gt;Our codebase has about a hundred JavaScript files and 96 Jade templates. Around 7,500 lines of server-side code. 352 commits &amp;ndash; 228 mine, 123 Jyoti&amp;rsquo;s. The readme is two lines. The todo list has two items &amp;ndash; one about image upload paths, one about a &lt;code&gt;bodyParser()&lt;/code&gt; deprecation we never got around to fixing.&lt;/p&gt;
&lt;p&gt;This is what a web application looks like when two people build the whole thing.&lt;/p&gt;
&lt;h2 id="the-split"&gt;The split&lt;/h2&gt;
&lt;p&gt;I own backend, database, and the graph model. Jyoti owns frontend &amp;ndash; views, templates, client-side interactions. There&amp;rsquo;s overlap in the middle. Routes are mine. The Jade templates that render those routes are hers. The &lt;code&gt;res.locals&lt;/code&gt; object is our contract &amp;ndash; I populate it with data from the middleware chain, she reads it in the templates. We rarely step on each other&amp;rsquo;s code.&lt;/p&gt;</description></item><item><title>Git history with Gource</title><link>https://blog.vnykmshr.com/writing/git-history-with-gource/</link><pubDate>Sat, 07 Jun 2014 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/git-history-with-gource/</guid><description>&lt;p&gt;I&amp;rsquo;d been watching YouTube videos of &lt;a href="https://code.google.com/p/gource/"&gt;Gource&lt;/a&gt; visualizations &amp;ndash; &lt;a href="https://www.youtube.com/watch?v=GTMC3g2Xy8c"&gt;Git&lt;/a&gt;, &lt;a href="http://www.youtube.com/watch?v=ZX0xCWANfW4"&gt;Homebrew&lt;/a&gt;, &lt;a href="https://www.youtube.com/watch?v=vsMUTsFdzr4"&gt;Node.js&lt;/a&gt;. Each commit becomes a moment in time, files branch out like a digital organism, contributors appear and disappear. Months of development condensed into a few minutes of organic growth.&lt;/p&gt;
&lt;p&gt;I pointed it at my blog&amp;rsquo;s git repository. Here&amp;rsquo;s &lt;a href="https://www.youtube.com/watch?v=jubNs7aXEvQ"&gt;what came out&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="setup"&gt;Setup&lt;/h2&gt;
&lt;p&gt;On macOS, Homebrew handles everything:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;brew update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;brew install gource ffmpeg
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The command that generates a video from a git repo:&lt;/p&gt;</description></item><item><title>Plans, not posts</title><link>https://blog.vnykmshr.com/writing/plans-not-posts/</link><pubDate>Wed, 30 Apr 2014 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/plans-not-posts/</guid><description>&lt;p&gt;I&amp;rsquo;ve decided to try my own gig. Against the steady cheque, against the version of my life that was already working. Writing it down so I can&amp;rsquo;t pretend I didn&amp;rsquo;t mean it.&lt;/p&gt;
&lt;p&gt;There are three of us, sketching the same thing on the same whiteboard. The idea is small and specific. Most of what gets shared online is opinion, or things that already happened. We want to build something where the unit is a &lt;em&gt;plan&lt;/em&gt; &amp;ndash; this Saturday, this street, this group, this thing we&amp;rsquo;re going to do. Friends see it, say they&amp;rsquo;re in, and now it&amp;rsquo;s on a calendar as a real thing.&lt;/p&gt;</description></item><item><title>On Phabricator</title><link>https://blog.vnykmshr.com/writing/on-phabricator/</link><pubDate>Sun, 01 Sep 2013 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/on-phabricator/</guid><description>&lt;p&gt;I&amp;rsquo;ve been using Phabricator for several months now. Code review happened before Phab too &amp;ndash; we weren&amp;rsquo;t shipping blind. Years of SVN, then Mercurial hosted on Unfuddle for a while. Reviews ran through email threads, commit comments, someone walking over to your desk. It worked. But the review was always a side channel. The diff wasn&amp;rsquo;t a first-class thing. You&amp;rsquo;d commit, someone would look at it, feedback would come through whatever medium was handy, you&amp;rsquo;d iterate, it would go in. Review happened &lt;em&gt;around&lt;/em&gt; the code, not &lt;em&gt;through&lt;/em&gt; a tool built for it.&lt;/p&gt;</description></item><item><title>Node.js style guide</title><link>https://blog.vnykmshr.com/writing/nodejs-style-guide/</link><pubDate>Wed, 20 Feb 2013 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/nodejs-style-guide/</guid><description>&lt;p&gt;We&amp;rsquo;re a Node.js team of about 25 developers, most of them fresh out of college. Node was new to everyone. This is the style guide we put together to keep the codebase consistent.&lt;/p&gt;
&lt;p&gt;Based on &lt;a href="http://nodeguide.com/style.html"&gt;Felix&amp;rsquo;s Node.js Style Guide&lt;/a&gt; with our own picks where his guide left things open. Read Felix&amp;rsquo;s first &amp;ndash; this extends it.&lt;/p&gt;
&lt;h2 id="formatting"&gt;Formatting&lt;/h2&gt;
&lt;p&gt;2 spaces. No tabs. No discussion.&lt;/p&gt;
&lt;p&gt;Trailing whitespace: strip it. Your editor should handle this. If it doesn&amp;rsquo;t, fix your editor.&lt;/p&gt;</description></item><item><title>History as communication</title><link>https://blog.vnykmshr.com/writing/git-history-as-communication/</link><pubDate>Mon, 18 Feb 2013 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/git-history-as-communication/</guid><description>&lt;p&gt;Most teams treat git history as a side effect. You work, you commit, whatever ends up in the log is the log. Merge commits pile up. &amp;ldquo;WIP&amp;rdquo; and &amp;ldquo;fix typo&amp;rdquo; and &amp;ldquo;actually working now&amp;rdquo; sit next to meaningful changes. The history is technically accurate but communicates nothing.&lt;/p&gt;
&lt;p&gt;The alternative: treat history as something you write, not something that happens to you. The commit log is the one piece of documentation that&amp;rsquo;s always in sync with the code &amp;ndash; because it &lt;em&gt;is&lt;/em&gt; the code&amp;rsquo;s changelog. If the history is incoherent, you&amp;rsquo;ve wasted that.&lt;/p&gt;</description></item><item><title>Starting over</title><link>https://blog.vnykmshr.com/writing/starting-over/</link><pubDate>Tue, 05 Feb 2013 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/starting-over/</guid><description>&lt;p&gt;Every now and then you want to start over. This blog was long overdue for it. Feels good to tear it down and rebuild.&lt;/p&gt;
&lt;p&gt;The old setup was WordPress on &lt;a href="http://nearlyfreespeech.net/"&gt;NearlyFreeSpeech.net&lt;/a&gt;. NFSN deserves credit &amp;ndash; their pay-as-you-go model is honest and the value is real. But WordPress started feeling like a constraint. I spend my days building custom solutions. Using a one-size-fits-all CMS for my own site felt wrong.&lt;/p&gt;
&lt;p&gt;So I built a blog engine.&lt;/p&gt;</description></item><item><title>The dispatch desk</title><link>https://blog.vnykmshr.com/writing/the-dispatch-desk/</link><pubDate>Thu, 20 Sep 2012 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/the-dispatch-desk/</guid><description>&lt;p&gt;The warehouse is in the basement. Three-floor office, one floor down. Inventory on open metal shelves &amp;ndash; row by column, every product a known address. I&amp;rsquo;ve been to bigger warehouses. The kind where one end isn&amp;rsquo;t visible from the other and you can&amp;rsquo;t tell what&amp;rsquo;s going on at a glance. This one isn&amp;rsquo;t like that. You can stand at the door and see the whole operation.&lt;/p&gt;
&lt;p&gt;An order comes in upstairs. The printout arrives at the front desk, gets handed over as a pick list &amp;ndash; reordered so a person can fetch the items in a single sequential pass through the aisles. The basket goes through quality check, then into the black box &amp;ndash; three layers, bubble wrap, thermocol where it matters. A label with tracking comes off a printer and gets pasted on. The box moves to the dispatch desk. The courier comes by later in the day. Two or three days to the customer. Same-day if they&amp;rsquo;re close.&lt;/p&gt;</description></item><item><title>Clean designs</title><link>https://blog.vnykmshr.com/writing/clean-designs/</link><pubDate>Thu, 28 Oct 2010 00:00:00 +0000</pubDate><guid>https://blog.vnykmshr.com/writing/clean-designs/</guid><description>&lt;p&gt;Two years ago I walked into a classroom in our office. Not a meeting room. An actual classroom, whiteboard, rows of chairs. The company had hired an instructor to teach the new hires Java. Two hours a day, three days a week, for three months.&lt;/p&gt;
&lt;p&gt;The training gave me syntax. Objects and classes. How inheritance works. What an interface is. The words for the things you do in code. Every week we wrote a small program and the instructor reviewed it.&lt;/p&gt;</description></item></channel></rss>