<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Articles on @zhisme :: signal over noise</title><link>https://zhisme.com/articles/</link><description>Recent content in Articles on @zhisme :: signal over noise</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Thu, 18 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://zhisme.com/articles/index.xml" rel="self" type="application/rss+xml"/><item><title>Not Best Time For An Open Source Contributions</title><link>https://zhisme.com/articles/not-best-time-for-open-source-contributions/</link><pubDate>Thu, 18 Jun 2026 00:00:00 +0000</pubDate><guid>https://zhisme.com/articles/not-best-time-for-open-source-contributions/</guid><description>&lt;p>If intro sounds like an existential crisis to you, then yes – it should!&lt;/p>
&lt;p>In the times before AI, there was a reason. You could add this to your CV and it would be valuable, someone could admire your work, find your PR, and even debate the decisions you made during an interview.&lt;br>
Some other resources, like the old Stack Overflow Jobs, allowed you to add your open-source contributions as widgets visible to anyone, and they had a very prominent place on that HTML page.&lt;/p></description></item><item><title>The Constant Frozen at Boot Bug: A Ruby Exercise For An Interview</title><link>https://zhisme.com/articles/ruby-constant-frozen-at-boot/</link><pubDate>Wed, 10 Jun 2026 00:00:00 +0000</pubDate><guid>https://zhisme.com/articles/ruby-constant-frozen-at-boot/</guid><description>&lt;p>I like interview questions that come from real incidents instead of a puzzle book. You can&amp;rsquo;t google your way out of them, and the candidate&amp;rsquo;s reasoning maps directly onto the job. This one came from a payment service. It looks trivial. It is not.&lt;/p>
&lt;p>I&amp;rsquo;ve stripped the production code and rebuilt the same shape around a fake payment router. The bug is identical; the names are not.&lt;/p>
&lt;h2 id="the-question">The Question&lt;/h2>
&lt;blockquote>
&lt;p>Here is a class that routes payments to a gateway. Occasionally a charge is&lt;br>
written to the database with &lt;code>method_id = NULL&lt;/code>, even though the payment method&lt;br>
clearly exists in the &lt;code>payment_methods&lt;/code> table. No exception is raised. The only&lt;br>
thing that reliably fixes it is restarting the process. Find the bug.&lt;/p></description></item><item><title>LLM Strikes Back But Not The Way We Wanted</title><link>https://zhisme.com/articles/llm-strikes-back-not-the-way-we-wanted/</link><pubDate>Fri, 29 May 2026 00:00:00 +0000</pubDate><guid>https://zhisme.com/articles/llm-strikes-back-not-the-way-we-wanted/</guid><description>&lt;p>AI strikes back, but not the way we wanted.&lt;/p>
&lt;p>Recently I had an interview with a recruiter — a very interesting and unexpected interview for me. It&amp;rsquo;s a funny story that can teach you something and make you vigilant.&lt;br>
The interview started in a very cliché way: asking me about my experience, why I left my previous company, what I&amp;rsquo;m looking for, and what my goals are for a new workplace.&lt;/p></description></item><item><title>Give Your LLM Brevity</title><link>https://zhisme.com/articles/give-your-llm-brevity/</link><pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate><guid>https://zhisme.com/articles/give-your-llm-brevity/</guid><description>&lt;blockquote>
 &lt;div class="blockquote-text">
 
Brevity is the Sister of Talent

 &lt;/div>
 &lt;div class="blockquote-author">
 &lt;div class="blockquote-author__pic">
 
 
 &lt;picture>
 &lt;source srcset="https://zhisme.com/articles/give-your-llm-brevity/chekhov.jpg">
 &lt;img src="https://zhisme.com/articles/give-your-llm-brevity/chekhov.jpg" alt="A.P. Chekhov">
 &lt;/picture>
 
 
 &lt;/div>
 &lt;div class="blockquote-author__content">
 &lt;div class="blockquote-author__name">A.P. Chekhov&lt;/div>
 &lt;div class="blockquote-author__position">&lt;/div>
 &lt;/div>
 &lt;/div>
&lt;/blockquote>

&lt;h2 id="why">Why?!&lt;/h2>
&lt;p>I don&amp;rsquo;t want to read invented machinery poems from an LLM about why it chose &lt;code>BigDecimal(0.5)&lt;/code> instead of a literal &lt;code>0.5&lt;/code> and writes 3 paragraphs defending a choice I didn&amp;rsquo;t ask about.&lt;br>
I don&amp;rsquo;t want to read invented nonsense that I have no time for.&lt;br>
If I don&amp;rsquo;t like something, I&amp;rsquo;ll ask to reimplement/refactor, or in rare cases request elaboration.&lt;br>
Then I will cover it with the needed tests until it satisfies me.&lt;br>
If you&amp;rsquo;re like me, you don&amp;rsquo;t want to spend time on that.&lt;/p></description></item><item><title>Multiple Git Configs Per Directory</title><link>https://zhisme.com/articles/multiple-git-configs-per-directory/</link><pubDate>Mon, 30 Mar 2026 00:00:00 +0000</pubDate><guid>https://zhisme.com/articles/multiple-git-configs-per-directory/</guid><description>&lt;h2 id="the-problem">The Problem&lt;/h2>
&lt;p>You have a personal GitHub and a work GitLab (or multiple work accounts). Your global &lt;code>~/.gitconfig&lt;/code> has your personal email. You clone a work repo, make a commit, push — and now your personal email is in the company git history. haha-haha classic..&lt;/p>
&lt;p>You could run &lt;code>git config user.email&lt;/code> in every new repo you clone. But you&amp;rsquo;ll forget. You always forget. But this is a boring routine, why do this?&lt;/p></description></item><item><title>Practical Useful Commands for Claude</title><link>https://zhisme.com/articles/practical-useful-commands-for-claude/</link><pubDate>Tue, 17 Mar 2026 00:00:00 +0000</pubDate><guid>https://zhisme.com/articles/practical-useful-commands-for-claude/</guid><description>&lt;p>These are commands I use often and see a lot of value from. I advise you at least to consider using them in case you haven&amp;rsquo;t tried them yet.&lt;/p>
&lt;h2 id="commands">Commands&lt;/h2>
&lt;ol>
&lt;li>&lt;code>claude --worktree&lt;/code> or &lt;code>claude -w&lt;/code>&lt;/li>
&lt;/ol>
&lt;p>In case you want multiple agents to run simultaneously, this option was designed for it. Each Claude agent gets its own version of the repo so they won&amp;rsquo;t interfere with each other. Where can you use it? Let&amp;rsquo;s say you&amp;rsquo;re migrating something to a new architecture and there are multiple services that need changes, but they&amp;rsquo;re located in a monorepo. With this option, each agent will be moving its own service or &amp;ldquo;folder&amp;rdquo; if you want, without getting conflicts with others.&lt;/p></description></item><item><title>Disable Co-Authored-By Claude in Git Commits</title><link>https://zhisme.com/articles/disable-co-authored-by-claude-in-git-commits/</link><pubDate>Fri, 27 Feb 2026 00:00:00 +0000</pubDate><guid>https://zhisme.com/articles/disable-co-authored-by-claude-in-git-commits/</guid><description>&lt;h2 id="solution">Solution&lt;/h2>
&lt;p>Open &lt;code>~/.claude/settings.json&lt;/code> with your favorite editor and add this to your json config. This is taken from Claude docs&lt;sup id="fnref:1">&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref">1&lt;/a>&lt;/sup>&lt;/p>
&lt;pre>&lt;code class="language-json">{
 // ...
 &amp;quot;attribution&amp;quot;: {
 &amp;quot;commit&amp;quot;: &amp;quot;&amp;quot;,
 &amp;quot;pr&amp;quot;: &amp;quot;&amp;quot;
 }
}
&lt;/code>&lt;/pre>
&lt;h2 id="why">Why&lt;/h2>
&lt;p>This actually makes no sense and I agree with Rob Pike&amp;rsquo;s take on that&lt;sup id="fnref:2">&lt;a href="#fn:2" class="footnote-ref" role="doc-noteref">2&lt;/a>&lt;/sup>. It just adds non-readable boilerplate that does not add any value to the git commit. If it was committed by some guy I expect him to take responsibility of that commit, not some excuse like &amp;ldquo;that was written by Claude, sorry I didn&amp;rsquo;t check&amp;rdquo;. So it makes &lt;strong>no sense&lt;/strong> at all, we are blind to that string anyway. Git commits should be atomic, simple and readable, not overwhelmed by nonsense. The trick above will help you with that.&lt;/p></description></item><item><title>OpenClaw Chameleon Hype</title><link>https://zhisme.com/articles/openclaw-chameleon/</link><pubDate>Wed, 11 Feb 2026 00:00:00 +0000</pubDate><guid>https://zhisme.com/articles/openclaw-chameleon/</guid><description>&lt;h2 id="the-chameleon-with-claws">The Chameleon With Claws&lt;/h2>
&lt;p>clawdbot/moltbot/&lt;a href="https://github.com/openclaw/openclaw">OpenClaw&lt;/a> — this chameleon flew through our tight-knit tech world and generated a spectacular amount of hype. 184k GitHub stars in the last month alone. For context, Rails has 56k stars after nearly 20 years.&lt;/p>
&lt;p>So what awaits this clawed chameleon — a rapid rise followed by an equally rapid fall?&lt;/p>
&lt;h2 id="what-it-actually-is">What It Actually Is&lt;/h2>
&lt;p>If you boil down what this tool does: it&amp;rsquo;s a daemon running on your machine that has access to &lt;em>everything&lt;/em> on your computer, configured through plain text &lt;code>.md&lt;/code> files for whatever tasks you need.&lt;/p></description></item><item><title>How to Set Up Browser MCP in Claude Code</title><link>https://zhisme.com/articles/setup-browser-mcp-claude/</link><pubDate>Sat, 24 Jan 2026 00:00:00 +0000</pubDate><guid>https://zhisme.com/articles/setup-browser-mcp-claude/</guid><description>&lt;h2 id="how-to-set-up-mcp-for-browser">How to set up MCP for browser&lt;/h2>
&lt;ol>
&lt;li>Create &lt;code>.mcp.json&lt;/code> in your project directory with the following content:&lt;/li>
&lt;/ol>
&lt;pre>&lt;code class="language-json">{
 &amp;quot;mcpServers&amp;quot;: {
 &amp;quot;chrome-devtools&amp;quot;: {
 &amp;quot;command&amp;quot;: &amp;quot;npx&amp;quot;,
 &amp;quot;args&amp;quot;: [&amp;quot;-y&amp;quot;, &amp;quot;chrome-devtools-mcp@latest&amp;quot;]
 }
 }
}
&lt;/code>&lt;/pre>
&lt;ol start="2">
&lt;li>Then run the following command in your terminal:&lt;/li>
&lt;/ol>
&lt;pre>&lt;code class="language-sh">claude mcp add chrome-devtools --scope user npx chrome-devtools-mcp@latest
&lt;/code>&lt;/pre>
&lt;ol start="3">
&lt;li>Then in Claude Code, run &lt;code>/mcp&lt;/code> to verify the connection:&lt;/li>
&lt;/ol>
&lt;pre>&lt;code class="language-sh"># start claude code cli
claude
# run /mcp inside cli
/mcp
─────────────────────────────────────────────────────────────────────────────────
 Manage MCP servers
 2 servers

 Project MCPs (/Users/zhisme/projects/my-project/.mcp.json)
 ❯ chrome-devtools · ✔ connected
&lt;/code>&lt;/pre>
&lt;ol start="4">
&lt;li>Afterwards, run a sample command to verify that the browser MCP can start:&lt;/li>
&lt;/ol>
&lt;pre>&lt;code class="language-sh"> ▐▛███▜▌ Claude Code v2.1.17
▝▜█████▛▘ Opus 4.5 · Claude Max
 ▘▘ ▝▝ ~/dev/projects/new-magtuner/mt-editor

❯ open with browser mcp url google.com

⏺ chrome-devtools - navigate_page (MCP)(type: &amp;quot;url&amp;quot;, url:
 &amp;quot;https://www.google.com&amp;quot;)
 ⎿  # navigate_page response
 Successfully navigated to https://www.google.com.
 ## Pages
 1: https://www.google.com/ [selected]

⏺ Opened google.com in the browser. The page is loaded and selected.
&lt;/code>&lt;/pre>
&lt;p>If you see a Google Chrome for Testing window like in the screenshot below, then everything is set up correctly. You can now tell Claude to visually verify your rendered pages.&lt;br>
&lt;figure>&lt;img src="https://zhisme.com/articles/setup-browser-mcp-claude/browsermcp.png"
 alt="Google chrome via browser mcp">&lt;figcaption>
 &lt;p>Google chrome via browser mcp&lt;/p></description></item><item><title>Ruby IO buffering</title><link>https://zhisme.com/articles/ruby-io-buffering/</link><pubDate>Fri, 16 Jan 2026 00:00:00 +0000</pubDate><guid>https://zhisme.com/articles/ruby-io-buffering/</guid><description>&lt;p>Your Kibana/Cloudwatch/Grafana have different timestamps, you don&amp;rsquo;t see recent logs from your application. Why is that? You may ask. Some QA reports that your application is not working/was not deployed, asking you to review the deploy process. Or even worse: asking your devops colleagues to &amp;ldquo;something went wrong&amp;rdquo; with last deployment could you check?&lt;/p>
&lt;p>You login into your shell running &lt;code>kubectl get pods&lt;/code> to verify timestamps update or checking Helm releases &lt;code>helm ls&lt;/code>. But everything seems fine, everything deployed. CI/CD is green, all timestamps updated. But yet. QA does not see the logs. Where have they gone?&lt;/p></description></item><item><title>Theory vs Practice: Why Technical Interviews Go Wrong</title><link>https://zhisme.com/articles/theory-vs-practice-why-technical-interviews-go-wrong/</link><pubDate>Mon, 15 Dec 2025 00:00:00 +0000</pubDate><guid>https://zhisme.com/articles/theory-vs-practice-why-technical-interviews-go-wrong/</guid><description>&lt;h2 id="tldr">TL;DR&lt;/h2>
&lt;p>&lt;strong>Match interview complexity to job complexity.&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Interview for what the job actually requires&lt;/li>
&lt;li>System design interviews test interview prep, not engineering ability&lt;/li>
&lt;li>Copying FAANG processes for non-FAANG problems is cargo cult&lt;/li>
&lt;li>Knowledge you don&amp;rsquo;t use, you lose&lt;/li>
&lt;/ul>
&lt;h2 id="an-exaggerated-hiring-story">An Exaggerated Hiring Story&lt;/h2>
&lt;p>HR contacts an engineer and asks them:&lt;/p>
&lt;blockquote>
Hi, %username%
&lt;p>We are fast-growing, extra efficient, super sufficient&lt;br>
LIST of Fortune 500 FORBES %company_name%&lt;/p>
&lt;p>Want to enlarge our staff and hire one another scintillating developer &lt;strong>(YOU)&lt;/strong> to join our super friendly team&lt;br>
Let&amp;rsquo;s schedule a call to share the details and proceed with next steps&lt;/p></description></item><item><title>A word on internet privacy</title><link>https://zhisme.com/articles/word-on-internet-privacy/</link><pubDate>Thu, 04 Dec 2025 00:00:00 +0000</pubDate><guid>https://zhisme.com/articles/word-on-internet-privacy/</guid><description>&lt;h2 id="the-sweetest-cookies">The Sweetest Cookies&lt;/h2>
&lt;p>I recently found that people fall into the illusion that all these dancing popups that block your sight from reading articles, news, and other sites, with some bullshit title stating &amp;ldquo;We value your privacy, please set your choice,&amp;rdquo; and that pressing reject will stop them from tracking you. But there&amp;rsquo;s always a tiny asterisk saying (we will store only necessary anonymous data to keep our product improving). But the thing is, your &lt;strong>cookies&lt;/strong> persist between site visits, and Google and other companies already put some data that can help identify you (but yes, it&amp;rsquo;s so-called &amp;ldquo;anonymous&amp;rdquo; data – nowhere does it state that you are, for example, &lt;em>Evgeny Zhdanov&lt;/em> and you&amp;rsquo;re interested in programming and drinking beer).&lt;/p></description></item><item><title>copy_with_context.nvim v3 Released</title><link>https://zhisme.com/articles/copy-with-context-v3-released/</link><pubDate>Mon, 24 Nov 2025 00:00:00 +0000</pubDate><guid>https://zhisme.com/articles/copy-with-context-v3-released/</guid><description>&lt;p>Previous post on original release is available at &lt;a href="https://zhisme.com/articles/copy-with-context-nvim">copy_with_context.nvim plugin released&lt;/a>.&lt;/p>
&lt;h2 id="whats-new-in-v3">What&amp;rsquo;s New in v3&lt;/h2>
&lt;h3 id="automatic-repository-url-generation">Automatic Repository URL Generation&lt;/h3>
&lt;p>The headline feature: when you copy code, the plugin now automatically includes a direct permalink to the code in your repository. No manual URL construction, no hunting for the right commit SHA—it just works.&lt;/p>
&lt;pre>&lt;code class="language-lua">-- When you copy this code, you get:
function authenticate(user)
 validate_credentials(user)
end

-- Output automatically includes:
-- app/controllers/auth_controller.rb:45-47
-- https://github.com/username/repo/blob/abc1234/app/controllers/auth_controller.rb#L45-L47
&lt;/code>&lt;/pre>
&lt;p>&lt;strong>What it does:&lt;/strong>&lt;/p></description></item><item><title>You Don’t Need Types in Ruby</title><link>https://zhisme.com/articles/you-dont-need-types-in-ruby/</link><pubDate>Wed, 29 Oct 2025 00:00:00 +0000</pubDate><guid>https://zhisme.com/articles/you-dont-need-types-in-ruby/</guid><description>&lt;p>There was a lively discussion on Hacker News &lt;a href="https://news.ycombinator.com/item?id=43938400">here&lt;/a> about &lt;a href="https://sorbet.org/">Sorbet&lt;/a> and static typing in Ruby that inspired this post.&lt;/p>
&lt;p>It’s fascinating how people try to make Ruby &lt;em>look&lt;/em> like a statically typed language. But this isn’t the first attempt — and every time, it ends up fighting against what Ruby fundamentally is.&lt;/p>
&lt;p>Turning Ruby into Java isn’t progress. It’s a step backward.&lt;br>
Let me explain why.&lt;/p>
&lt;h2 id="how-ruby-deals-with-types">How Ruby Deals with Types&lt;/h2>
&lt;p>Ruby is a dynamically typed, object-oriented language designed around message passing — an idea borrowed from &lt;a href="https://en.wikipedia.org/wiki/Smalltalk">Smalltalk&lt;/a>.&lt;/p></description></item><item><title>Reviewing "Angry Tests"</title><link>https://zhisme.com/articles/reviewing-angry-tests/</link><pubDate>Tue, 06 May 2025 00:00:00 +0000</pubDate><guid>https://zhisme.com/articles/reviewing-angry-tests/</guid><description>&lt;p>As software engineers, we’re used to writing tests — but we don’t always know how to write them well. We aim to cover the most significant lines of code, often guided by intuition. This book is a practical guide to writing better tests, and I found it to be a valuable resource for anyone involved in software testing — whether you&amp;rsquo;re a developer or a tester.&lt;/p>
&lt;p>You can find the book, purchase options, and more details here:&lt;br>
&lt;a href="https://www.yegor256.com/angry-tests.html" target="_blank" rel="noopener noreferrer">&lt;br>
Yegor&amp;rsquo;s site.&lt;br>
&lt;/a>&lt;br>
This book focuses on automated software testing — &lt;strong>what&lt;/strong> to test, and &lt;strong>how&lt;/strong>. It walks you through best practices and explains why solid testing is essential for long-term maintainability and support.&lt;/p></description></item><item><title>copy_with_context.nvim plugin released</title><link>https://zhisme.com/articles/copy-with-context-nvim/</link><pubDate>Sun, 13 Apr 2025 00:00:00 +0000</pubDate><guid>https://zhisme.com/articles/copy-with-context-nvim/</guid><description>&lt;p>I&amp;rsquo;m excited to announce the release of my new Neovim plugin, &lt;a href="https://github.com/zhisme/copy_with_context.nvim">copy_with_context.nvim&lt;/a>&lt;/p>
&lt;p>When sharing code snippets, it&amp;rsquo;s often useful to include the file path and line number for context. This plugin makes it easy to copy lines with this metadata. It is easier to understand the context of the code snippet when the file path and line number are included. Otherwise you have to do it manually. Copying snippet, then adding the line number &lt;em>(what if it is long config file? it is boring)&lt;/em>. We can automate it and do not waste our time.&lt;/p></description></item><item><title>lazy_names gem, how much time do you spend in console?</title><link>https://zhisme.com/articles/lazy-names/</link><pubDate>Sun, 12 Jan 2020 00:00:00 +0000</pubDate><guid>https://zhisme.com/articles/lazy-names/</guid><description>&lt;p>I&amp;rsquo;m happy to share the &lt;a href="https://github.com/zhisme/lazy_names?tab=readme-ov-file#lazy_names">lazy_names&lt;/a> gem!&lt;br>
This gem allows you to define a config file that maps long, namespaced constants to something simpler and more intuitive:&lt;/p>
&lt;pre>&lt;code class="language-yml">'Models::Users::CreditCard': 'UserCard'
&lt;/code>&lt;/pre>
&lt;p>I spend a lot of time in the console, which is why I originally wrote this gem. Here’s a quick look at my most frequently run commands from my Zsh history:&lt;/p>
&lt;pre>&lt;code class="language-sh">$: history | awk '{$1=&amp;quot;&amp;quot;; print $0}' | sort | uniq -c | sort -nr
 647 gs
 135 rc # rails console
 135 ls
 134 gd
 ...
&lt;/code>&lt;/pre>
&lt;p>Do you use the Ruby console much while developing? I personally like to check my code directly in the console — calling methods to inspect return values — especially in the early development stage before tests are written. Sometimes, I need to drop records from the database or build some structs on the fly.&lt;/p></description></item></channel></rss>