<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Calvin's Dev Logs</title>
    <link>https://calvin.my/</link>
    <description>Calvin's dev logs — code snippets, demos, tutorials, and solutions across software topics. Tracking my coding journey and discoveries.</description>
    <language>en-us</language>
    <pubDate>Wed, 16 Sep 2026 21:03:36 +0800</pubDate>
    <atom:link href="https://calvin.my/feed" rel="self" type="application/rss+xml"/>
    <item>
      <title>Help password managers find your change password page</title>
      <link>https://calvin.my/posts/help-password-managers-find-your-change-password-page</link>
      <description>The post explains how Rails apps can help browsers and password managers locate password-change forms through a standardized well-known URL. The endpoint must exist at the site root and temporarily redirect to the actual password-change page rather than serving it directly. Other unknown well-known paths should not appear successful. A routing redirect implements this, while password-field autocomplete hints can improve support for automated password changes. Signed-out users may appropriately be redirected to login.</description>
      <pubDate>Wed, 16 Sep 2026 21:03:36 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:246</guid>
    </item>
    <item>
      <title>The "json" gem v3.0 upgrade broke Rails App</title>
      <link>https://calvin.my/posts/the-json-gem-v3-0-upgrade-broke-rails-app</link>
      <description>A json gem 3.0 upgrade can cause Rails tests to fail with misleading argument errors originating in session cookie decryption rather than application code. Full backtraces reveal the failure occurs when Rails deserializes JSON metadata. Rails has merged and backported a fix, but no release includes it yet. Teams can use the stable Rails branch or pin json to the 2.x series, while configuring dependency automation to avoid repeated 3.x upgrade proposals.</description>
      <pubDate>Thu, 10 Sep 2026 01:25:45 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:245</guid>
    </item>
    <item>
      <title>Cutting GitHub Actions bill in a Rails app</title>
      <link>https://calvin.my/posts/cutting-github-actions-bill-in-a-rails-app</link>
      <description>The post explains how a Rails team reduced private GitHub Actions costs without losing useful failure reporting. It combines short checks to avoid repeated runner setup, cancels outdated feature-branch runs, and adds job timeouts. It also reduces Dependabot frequency, separates unit and system tests so both results appear after failures while adjusting coverage checks, and explicitly limits workflow token permissions. The changes trade some parallelism for lower billed wall-clock time and more reliable feedback.</description>
      <pubDate>Tue, 08 Sep 2026 18:16:16 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:244</guid>
    </item>
    <item>
      <title>Migrating Rails System Tests from Selenium to Playwright</title>
      <link>https://calvin.my/posts/migrating-rails-system-tests-from-selenium-to-playwright</link>
      <description>The post outlines migrating Rails system tests from Selenium to Playwright through Capybara, often without rewriting the suite. It recommends auditing Selenium-specific calls and subtle behavioral differences, replacing dependencies, installing a version-matched Playwright CLI and Chromium, and updating the system-test driver and CI workflow. Translation work should remove obsolete Selenium flakiness workarounds while preserving application-level waits. Full-suite runs and fixed test seeds help validate the migration.</description>
      <pubDate>Mon, 31 Aug 2026 02:59:50 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:243</guid>
    </item>
    <item>
      <title>Migrate a Single Repository from Bitbucket to GitHub</title>
      <link>https://calvin.my/posts/migrate-a-single-repository-from-bitbucket-to-github</link>
      <description>This guide explains how to migrate a Bitbucket repository to GitHub while preserving its full branch, tag, and commit history. It covers required local tools and access, transferring repository references to an empty or intentionally overwritten destination, cleaning up temporary files, and recloning from GitHub. An optional step renames the default branch from master to main, followed by checks to confirm repository integrity and tracking.</description>
      <pubDate>Thu, 27 Aug 2026 12:03:14 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:242</guid>
    </item>
    <item>
      <title>Chrome on-device AI with Gemma4 (Aug 2026)</title>
      <link>https://calvin.my/posts/chrome-on-device-ai-with-gemma4-aug-2026</link>
      <description>The post evaluates Chrome’s developer-trial on-device Gemma4 summarizer against Nano v3 and a server-side model using a 1,300-word Rails deployment article. Gemma4 better captured the article’s update-from-2017 framing, while Nano often recited its structure. All outputs were usable but Gemma4 showed minor wording errors. Chrome’s API cannot identify or select the active model, so testing requires disabling alternatives. On-device summaries offer privacy, offline use, and no API cost, but remain unsuitable for unattended metadata.</description>
      <pubDate>Wed, 26 Aug 2026 01:33:57 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:241</guid>
    </item>
    <item>
      <title>Deploying Rails with Capistrano in 2026</title>
      <link>https://calvin.my/posts/deploying-rails-with-capistrano-in-2026</link>
      <description>An updated guide to deploying a modern Rails application with Capistrano explains changes since 2017, including encrypted credentials, Propshaft, Solid Queue, and Bundler 4. It covers initial project and server setup, shared files, Passenger, deployment checks, rollbacks, and worker restarts. The post also corrects outdated defaults by configuring Bundler, cleanup, conditional migrations, and Passenger behavior, and recommends pruning Bootsnap caches caused by release-specific paths.</description>
      <pubDate>Sat, 22 Aug 2026 16:45:47 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:240</guid>
    </item>
    <item>
      <title>Few ways to ask an AI provider how much credit you have left</title>
      <link>https://calvin.my/posts/few-ways-to-ask-an-ai-provider-how-much-credit-you-have-left</link>
      <description>Managing prepaid balances across AI providers requires different monitoring strategies because billing interfaces vary widely. DeepSeek and Kimi provide balances directly, while xAI requires a separate management credential and adjustment for its billing format. Anthropic and OpenAI expose spending rather than balances, so manual balance entries can serve as anchors for estimated remaining credit. Gemini offers no usable programmatic billing data, requiring manual console checks.</description>
      <pubDate>Wed, 19 Aug 2026 02:18:05 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:239</guid>
    </item>
    <item>
      <title>Rewriting a web app against a frozen API contract</title>
      <link>https://calvin.my/posts/rewriting-a-web-app-against-a-frozen-api-contract</link>
      <description>Rebuilding a live, unmaintained Rails application required preserving its frozen third-party interface while correcting internals. The team documented existing behavior separately from defects, delivered staged components with tests, and replayed captured traffic and database changes to expose every divergence. Screens were validated against production screenshots, and removals were documented. The rewrite also improved security and rate limiting, though browser test flakiness persisted. The main lesson: modernization was secondary to observing, reproducing, and proving real-world behavior.</description>
      <pubDate>Sun, 16 Aug 2026 15:19:52 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:238</guid>
    </item>
    <item>
      <title>Ruby Bundler’s cooldown Feature for Safer Gem Updates</title>
      <link>https://calvin.my/posts/ruby-bundler-s-cooldown-feature-for-safer-gem-updates</link>
      <description>Ruby Bundler 4.0.13 introduces a cooldown setting that filters out gem versions published within a chosen number of days. The feature aims to reduce supply-chain risk by allowing time for newly released gems to be vetted and for potential account-takeover incidents to emerge. Developers can apply the setting through dependency configuration or Bundler options, and can override it when immediate updates are necessary.</description>
      <pubDate>Sat, 06 Jun 2026 14:56:50 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:237</guid>
    </item>
    <item>
      <title>SQLite3 as Production Database</title>
      <link>https://calvin.my/posts/sqlite3-as-production-database</link>
      <description>The post outlines production SQLite practices for Rails applications. It recommends splitting primary data, jobs, cache, and cable workloads into separate database files to isolate locking and WAL activity. Performance can be tuned through SQLite settings that increase caching, retry lock contention, and keep temporary data in memory, while accounting for memory limits. It also stresses establishing and testing a backup-and-restore process.</description>
      <pubDate>Fri, 08 May 2026 16:20:55 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:236</guid>
    </item>
    <item>
      <title>Interesting features in Claude Code CLI</title>
      <link>https://calvin.my/posts/interesting-features-in-claude-code-cli</link>
      <description>The post highlights several Claude Code CLI features aimed at personalization and workflow review. Users can customize the status line with contextual details, enable push-to-talk voice input, and access an official sticker store. An alternate terminal layout can keep the input area fixed at the bottom, reducing visual flicker. The insights feature analyzes the previous month’s sessions, summarizing usage patterns and suggesting areas to improve.</description>
      <pubDate>Sun, 05 Apr 2026 12:54:42 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:235</guid>
    </item>
    <item>
      <title>Warning: connection is not using a post-quantum key exchange algorithm</title>
      <link>https://calvin.my/posts/warning-connection-is-not-using-a-post-quantum-key-exchange-algorithm</link>
      <description>OpenSSH may warn that a connection lacks post-quantum key exchange protection against future “store now, decrypt later” attacks. The post explains that this is a precaution rather than an immediate security incident. Users can address it by upgrading remote servers to OpenSSH 10 or later, testing client-side preferences for quantum-resistant exchanges, or retaining compatible methods when servers are not ready. The warning can also be suppressed, though doing so does not improve security.</description>
      <pubDate>Thu, 26 Mar 2026 14:18:18 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:234</guid>
    </item>
    <item>
      <title>Warning 'mysql_native_password' authentication type is disabled by default in MySQL 8.4</title>
      <link>https://calvin.my/posts/warning-mysql_native_password-authentication-type-is-disabled-by-default-in-mysql-8-4</link>
      <description>Upgrading from MySQL 8.0 to 8.4 may warn that accounts still use the deprecated mysql_native_password authentication method, which is disabled by default in 8.4 and planned for removal. The post recommends first updating to the latest 8.0 release, identifying affected users, migrating them to caching_sha2_password, notifying users if passwords change, and testing each updated connection.</description>
      <pubDate>Thu, 26 Mar 2026 01:07:53 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:233</guid>
    </item>
    <item>
      <title>The Chrome DevTool MCP General Availability</title>
      <link>https://calvin.my/posts/the-chrome-devtool-mcp-general-availability</link>
      <description>Chrome DevTools MCP is now generally available in Chrome 146’s stable channel, enabling AI command-line tools to connect to a running browser through remote debugging. The post outlines setup for Gemini CLI and Claude CLI, then demonstrates Claude inspecting a local page with screenshots, identifying unused layout space, applying form-width fixes, reloading the page, and verifying that the updated interface uses horizontal space more effectively.</description>
      <pubDate>Sun, 15 Mar 2026 13:07:37 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:232</guid>
    </item>
    <item>
      <title>Enabling agentic coding in Xcode</title>
      <link>https://calvin.my/posts/enabling-agentic-coding-in-xcode</link>
      <description>The post explains how to enable Xcode 26.3’s agentic coding feature by opening the Coding Agent panel, selecting a supported provider, linking an active subscription, installing the provider’s agent tool, and authorizing quota usage. Once setup succeeds, developers can use the chat interface to ask questions or request tasks, report issues from responses, and switch to the Claude Agent for coding work.</description>
      <pubDate>Sun, 01 Mar 2026 12:36:28 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:231</guid>
    </item>
    <item>
      <title>Gemini 3.1 Flash image (Nano Banana 2) preview</title>
      <link>https://calvin.my/posts/gemini-3-1-flash-image-nano-banana-2-preview</link>
      <description>The post reviews Google’s February 2026 preview of Gemini 3.1 Flash Image, also called Nano Banana 2. It highlights API additions including 512-pixel output, expanded aspect ratios, search grounding with image search, and combined text-and-image responses. Tests demonstrate small icon generation, extreme panoramic and vertical formats, and a search-grounded currency exchange board. The examples suggest the model can follow detailed composition requests and produce current-rate imagery with reasonable accuracy.</description>
      <pubDate>Fri, 27 Feb 2026 15:06:26 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:230</guid>
    </item>
    <item>
      <title>Rails Solid Queue async mode</title>
      <link>https://calvin.my/posts/rails-solid-queue-async-mode</link>
      <description>Solid Queue version 1.3.0 restores async mode, which runs the supervisor, worker, dispatcher, and scheduler within one process rather than separate processes. This design aims to reduce memory consumption and improve suitability for constrained deployment environments. The post explains enabling the mode through the job startup configuration and verifying it by checking whether the supervisor is identified as running in async rather than fork mode.</description>
      <pubDate>Wed, 07 Jan 2026 11:36:50 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:229</guid>
    </item>
    <item>
      <title>Adding a catch all black hole blocks in Nginx</title>
      <link>https://calvin.my/posts/adding-a-catch-all-black-hole-blocks-in-nginx</link>
      <description>The post describes creating a default Nginx “black hole” server block for requests that do not match configured domains. It uses a dummy self-signed certificate for HTTPS and drops unmatched traffic, including scans sent directly to an IP address or requests with unexpected host headers. This reduces unnecessary bandwidth use, prevents accidental routing to applications, and avoids exposing certificates for legitimate sites when scanners connect over HTTPS.</description>
      <pubDate>Mon, 05 Jan 2026 13:21:56 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:228</guid>
    </item>
    <item>
      <title>Using simplecov code coverage with Rails &amp; Minitest</title>
      <link>https://calvin.my/posts/using-simplecov-code-coverage-with-rails-minitest</link>
      <description>The post explains how to add SimpleCov coverage reporting to a Rails 8 application using Minitest. It outlines installing the coverage tool, initializing it early in the test helper with branch coverage and separate suite names, and optionally filtering short scaffold files or defining custom source groups. Running unit and system tests together merges results, which are written to the coverage output directory.</description>
      <pubDate>Fri, 02 Jan 2026 14:23:46 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:227</guid>
    </item>
    <item>
      <title>A simple Ruby::Box demo</title>
      <link>https://calvin.my/posts/a-simple-ruby-box-demo</link>
      <description>Ruby 4.0’s experimental Ruby::Box feature creates isolated execution spaces within one process. The post compares direct evaluation of LLM-generated Ruby with evaluation inside a box, using an example where malicious code attempts to read sensitive application state. Direct execution exposes credentials, while the box prevents access to those values. Ruby::Box may help build safer LLM code-execution tools, but it still requires safeguards and is not production-ready due to known issues.</description>
      <pubDate>Sat, 27 Dec 2025 15:21:58 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:226</guid>
    </item>
    <item>
      <title>Litestream 0.5.x updates</title>
      <link>https://calvin.my/posts/litestream-0-5-x-updates</link>
      <description>This post outlines setting up Litestream 0.5.x to continuously replicate SQLite databases. It covers installing the release appropriate to the host architecture, enabling the service, and configuring database replicas for local storage or Amazon S3 with a chosen synchronization interval. Readers can verify backups through stored snapshots and restore a database by reinstalling Litestream, supplying valid S3 credentials with required permissions, and running the restore process.</description>
      <pubDate>Thu, 25 Dec 2025 16:29:32 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:225</guid>
    </item>
    <item>
      <title>Build a simple app that describes an image and works offline</title>
      <link>https://calvin.my/posts/build-a-simple-app-that-describes-an-image-and-works-offline</link>
      <description>The post outlines an Android app that generates English image descriptions using Gemini’s on-device Image Description API. It requires Android SDK 29 or later and supported flagship hardware, not an emulator. The implementation initializes the descriptor, checks device and model availability, prompts users to download the model when needed, and submits selected images for inference. After the model is installed, descriptions work without an internet connection; resources should be closed afterward.</description>
      <pubDate>Sun, 14 Dec 2025 21:11:09 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:224</guid>
    </item>
    <item>
      <title>API Error: claude block must have a corresponding `tool_use` block in the previous message</title>
      <link>https://calvin.my/posts/api-error-claude-block-must-have-a-corresponding-tool_use-block-in-the-previous-message</link>
      <description>This post addresses a Claude Code API error that prevents further conversation when a Claude block lacks a matching prior tool-use block. Suggested recovery options are starting a new session, compacting history while retaining a summary of context, or rewinding one or two checkpoints. Rewind lets users restore conversation history, code changes, or both, removing the problematic recent exchange and allowing work to continue.</description>
      <pubDate>Tue, 02 Dec 2025 18:39:00 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:223</guid>
    </item>
    <item>
      <title>Gemini 3 Pro image (Nano Banana Pro) early preview</title>
      <link>https://calvin.my/posts/gemini-3-pro-image-nano-banana-pro-early-preview</link>
      <description>An early API review of Google’s Nano Banana Pro image model examines generation, reference-guided output, conversational editing, mixed realistic and illustrative scenes, and handwriting-style math solutions. The preview supports selectable resolutions up to 4K and as many as 14 reference images. Tests produced strong results, but requests took two to four minutes. Developers must handle mandatory reasoning signatures, higher token use, large signature storage, and sizable 4K files, favoring background streaming for long-running jobs.</description>
      <pubDate>Sun, 23 Nov 2025 22:37:47 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:222</guid>
    </item>
    <item>
      <title>Adding sub-resource integrity with Importmap &amp; Rails</title>
      <link>https://calvin.my/posts/adding-sub-resource-integrity-with-importmap-rails</link>
      <description>The post explains how to enable Subresource Integrity for Rails assets, especially files generated during builds whose hashes must be recalculated. Rails can generate integrity hashes by selecting an algorithm, enabling integrity on stylesheet tags, and activating Importmap support in its configuration. The result is generated stylesheet and module preload tags containing integrity attributes, allowing browsers to verify that loaded assets have not been altered.</description>
      <pubDate>Sat, 15 Nov 2025 22:53:12 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:221</guid>
    </item>
    <item>
      <title>Adding sub-resource integrity with Vite build</title>
      <link>https://calvin.my/posts/adding-sub-resource-integrity-with-vite-build</link>
      <description>The post explains how to add Subresource Integrity hashes to assets generated by Vite builds. Because Vite does not create these hashes by default, the author uses an open-source manifest plugin, adds it to the project configuration, and rebuilds the application. The resulting manifest includes integrity values, which can be applied to rendered script tags. The plugin supports alternative hashing algorithms, including SHA-512.</description>
      <pubDate>Thu, 13 Nov 2025 10:28:47 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:220</guid>
    </item>
    <item>
      <title>Install the missing ext-intl PHP extension in MacOS</title>
      <link>https://calvin.my/posts/install-the-missing-ext-intl-php-extension-in-macos</link>
      <description>Homebrew disabled PHP’s intl extension in its PHP formulas, which can break applications that rely on internationalization support after an update. The post outlines two remedies: use a different PHP distribution or compile PHP manually, or install Homebrew’s separate intl extension package alongside PHP. This change means macOS developers may need to explicitly add the extension when upgrading or configuring PHP environments.</description>
      <pubDate>Wed, 12 Nov 2025 15:58:58 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:219</guid>
    </item>
    <item>
      <title>New ways to install Claude Code on macOS</title>
      <link>https://calvin.my/posts/new-ways-to-install-claude-code-on-macos</link>
      <description>Claude Code on macOS can now be installed through a shell-based installer or Homebrew, in addition to the existing NPM distribution. The new options remove NPM as a prerequisite. Users migrating from the NPM version should first uninstall it, then choose one of the alternative installation methods. Claude Code also supports automatic updates, while Homebrew users can manage updates through Homebrew.</description>
      <pubDate>Tue, 04 Nov 2025 20:47:53 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:218</guid>
    </item>
    <item>
      <title>Breaking change in net-http gem to exclude default content type</title>
      <link>https://calvin.my/posts/breaking-change-in-net-http-gem-to-exclude-default-content-type</link>
      <description>Net-http version 0.7.0 removes its default request content type, potentially changing behavior for applications and libraries that rely on it indirectly. Requests that previously sent form data without an explicit header may now be interpreted differently by APIs, as illustrated by a Google reCAPTCHA verification failure. Developers should review affected HTTP calls and explicitly set the appropriate Content-Type, rather than depending on net-http defaults.</description>
      <pubDate>Sat, 01 Nov 2025 16:57:41 +0800</pubDate>
      <guid isPermaLink="false">calvin.my:article:217</guid>
    </item>
  </channel>
</rss>
